Files
tacker/tacker/tests/unit/vnfm/infra_drivers/openstack/test_openstack_driver.py
T
Takahiro Miyajima 7c8dbf3c6f Fix issue of healing after scale out v1 VNF
This patch is:
- The number of VNF instances in the stack list after SOL003 heal
  remains the number after scale out.
- About the `vnfcResourceInfo`, `virtualStorageResourceInfo`,
  and `vnfcInfo` of vnflcm show command after SOL003 heal and
  scale out, the number of VDUs is correct.
- About the `vnfcInfo` of vnflcm show command after scale out
  and scale in, the number of VDUs is correct.
- For the VNF using heat-translator package, after instantiate,
  the setting of `scaleStatus` of vnflcm show command is correct.
- Also about `vimLevelResourceType` of vnflcm show command after
  scale out, delete extra space before `OS::Nova::Server' or
  `OS::Cinder::Volume`.

Related patch(fix about CNF):
  https://review.opendev.org/c/openstack/tacker/+/922195

Closes-Bug: #2084621
Change-Id: I127ac59a66ec2daaf49487bbbfb721f0e9c97638
2024-11-22 00:26:46 +00:00

3764 lines
179 KiB
Python

# Copyright 2017 99cloud, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import copy
import ddt
import importlib
import json
import os
import requests
import tempfile
import yaml
from heatclient.v1 import resources
from oslo_serialization import jsonutils
from oslo_utils import timeutils
from tacker.common import exceptions
from tacker.common import utils as cutils
from tacker import context
from tacker.db.db_sqlalchemy import models
from tacker.extensions import vnfm
from tacker import objects
from tacker.objects import fields
from tacker.tests import constants
from tacker.tests.unit import base
from tacker.tests.unit.db import utils
from tacker.tests.unit.vnflcm import fakes
from tacker.tests.unit.vnfm.infra_drivers.openstack.fixture_data import client
from tacker.tests.unit.vnfm.infra_drivers.openstack.fixture_data import \
fixture_data_utils as fd_utils
from tacker.tests import utils as test_utils
from tacker.tests import uuidsentinel
from tacker.vnfm.infra_drivers.openstack import heat_client as hc
from tacker.vnfm.infra_drivers.openstack import openstack
from unittest import mock
vnf_dict = {
'instance_id': 'd1121d3c-368b-4ac2-b39d-835aa3e4ccd8'
}
class FakeVNFMPlugin(mock.Mock):
def __init__(self):
super(FakeVNFMPlugin, self).__init__()
def get_vnf(self, context, vnf_id):
filename = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "./data/",
'etsi_nfv/tosca_vnfd.yaml')
with open(filename) as f:
vnfd_dict = {'vnfd_simple': str(yaml.safe_load(f))}
return {
'attributes': {},
'status': 'ACTIVE',
'vnfd_id': 'e889e4fe-52fe-437d-b1e1-a690dc95e3f8',
'tenant_id': '13d2ca8de70d48b2a2e0dbac2c327c0b',
'vim_id': '3f41faa7-5630-47d2-9d4a-1216953c8887',
'instance_id': 'd1121d3c-368b-4ac2-b39d-835aa3e4ccd8',
'placement_attr': {'vim_name': 'kubernetes-vim'},
'id': '436aaa6e-2db6-4d6e-a3fc-e728b2f0ac56',
'name': 'cnf_create_1',
'vnfd': {
'attributes': vnfd_dict
}
}
class FakeAlarmPlugin():
def add_alarm_url_to_vnf(self, context, vnf):
return
class FakePlugin():
def get_vnf(self, context, id):
return vnf_dict
@ddt.ddt
class TestOpenStack(base.FixturedTestCase):
client_fixture_class = client.ClientFixture
sdk_connection_fixure_class = client.SdkConnectionFixture
def setUp(self):
super(TestOpenStack, self).setUp()
self.patcher = mock.patch(
'tacker.manager.TackerManager.get_service_plugins',
return_value={'VNFM': FakeVNFMPlugin()})
self.mock_manager = self.patcher.start()
self.openstack = openstack.OpenStack()
self.context = context.get_admin_context()
self.heat_url = client.HEAT_URL
self.glance_url = client.GLANCE_URL
self.instance_uuid = uuidsentinel.instance_id
self.stack_id = uuidsentinel.stack_id
self.auth_attr = None
self.plugin = None
self.json_headers = {'content-type': 'application/json',
'location': 'http://heat-api/stacks/'
+ self.instance_uuid + '/myStack/60f83b5e'}
self._mock('tacker.common.clients.OpenstackClients.heat', self.cs)
mock.patch('tacker.common.clients.OpenstackSdkConnection.'
'openstack_connection', return_value=self.sdk_conn).start()
self.mock_log = mock.patch('tacker.vnfm.infra_drivers.openstack.'
'openstack.LOG').start()
mock.patch('time.sleep', return_value=None).start()
def _nfv_sample(self, name):
return test_utils.test_etc_sample('etsi/nfv', name)
def _response_in_wait_until_stack_ready(self, status_list,
stack_outputs=True):
# response for heat_client's get()
for status in status_list:
url = self.heat_url + '/stacks/' + self.instance_uuid
json = {'stack': fd_utils.get_dummy_stack(stack_outputs,
status=status)}
self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
def _response_in_resource_get(self, id, res_name=None):
# response for heat_client's resource_get()
if res_name:
url = self.heat_url + '/stacks/' + id + ('/myStack/60f83b5e/'
'resources/') + res_name
else:
url = self.heat_url + '/stacks/' + id
json = {'resource': fd_utils.get_dummy_resource()}
self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
def _response_in_stack_get(self, id, stack_status='CREATE_COMPLETE'):
# response for heat_client's stack_get()
url = self.heat_url + '/stacks/' + id
json = {'stack': fd_utils.get_dummy_stack(status=stack_status)}
self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
def _response_in_stack_update(self, id):
# response for heat_client's stack_patch()
url = self.heat_url + '/stacks/' + id
self.requests_mock.register_uri('PATCH', url,
headers=self.json_headers)
def _response_resource_mark_unhealthy(self, id, resources,
raise_exception=False):
# response for heat_client's heatclient.resource_mark_unhealthy
if not resources:
return
class MyException(Exception):
pass
for resource in resources:
url = os.path.join(self.heat_url, 'stacks', id,
'myStack/60f83b5e/resources', resource['resource_name'])
if raise_exception:
self.requests_mock.register_uri('PATCH', url,
exc=MyException("Any stuff"))
else:
self.requests_mock.register_uri('PATCH', url)
def _json_load(self, input_file):
json_file = test_utils.test_etc_sample("lcm_instantiate_request",
input_file)
with open(json_file) as f:
json_dict = json.load(f)
return json_dict
def _read_file(self, scale_input_file=False):
if scale_input_file:
file_name = "hot_lcm_user_data_with_scale.yaml"
else:
file_name = "hot_lcm_user_data.yaml"
yaml_file = test_utils.test_etc_sample(file_name)
with open(yaml_file, 'r') as f:
yaml_file_dict = yaml.safe_load(f)
return yaml_file_dict
def _read_nested_file(self):
yaml_file = test_utils.test_etc_sample("nested_hot_data.yaml")
with open(yaml_file, 'r') as f:
yaml_file_dict = yaml.safe_load(f)
return yaml_file_dict
def _get_grant_obj(self, zoneid=None):
vim_assets = {
'compute_resource_flavours': [
{'vim_connection_id': uuidsentinel.vim_id,
'vnfd_virtual_compute_desc_id': 'VDU1',
'vim_flavour_id': 'm1.tiny'}],
'softwareImages': [
{'vim_connection_id': uuidsentinel.vim_id,
'vnfd_software_image_id': 'VDU1',
'vim_software_image_id': 'cirros'}
]}
res_add_resource = []
resource = {
'resource_definition_id': '2c6e5cc7-240d-4458-a683-1fe648351280',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
resource = {
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa9',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
resource = {
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa0',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
resource = {
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa1',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
vim_obj = {'id': '0b9c66bb-9e1f-4bb2-92c3-913074e52e2b',
'vim_id': uuidsentinel.vim_id,
'vim_type': 'openstack',
'access_info': {
'password': 'test_pw',
'username': 'test_user',
'region': 'test_region',
'tenant': uuidsentinel.tenant}}
if zoneid:
zone = {
'id': '5e4da3c3-4a55-412a-b624-843921f8b51d',
'zone_id': 'nova',
'vim_connection_id': uuidsentinel.vim_id}
else:
zone = {
'id': '5e4da3c3-4a55-412a-b624-843921f8b51d',
'zone_id': '',
'vim_connection_id': uuidsentinel.vim_id}
grant_dict = {}
grant_dict['id'] = 'c213e465-8220-487e-9464-f79104e81e96'
grant_dict['vnf_instance_id'] = uuidsentinel.vnf_instance_id
grant_dict['vnf_lcm_op_occ_id'] = uuidsentinel.vnf_lcm_op_occ_id
grant_dict['add_resources'] = []
grant_dict['add_resources'].extend(res_add_resource)
grant_dict['vim_assets'] = vim_assets
grant_dict['zones'] = [zone]
grant_dict['vim_connections'] = [vim_obj]
return grant_dict
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils._get_vnflcm_interface')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_normal(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_get_vnflcm_interface,
mock_format_base_hot):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils._get_vnflcm_interface')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_normal_with_scaling_group(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_get_vnflcm_interface,
mock_format_base_hot):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
scaling_group=True,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_normal_scaling")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = \
self._read_file(scale_input_file=True), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._create_stack_with_user_data')
@mock.patch('tacker.tosca.utils.get_scale_group')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils._get_vnflcm_interface')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_normal_with_scaling_group_and_scale_status(
self, mock_OpenstackClients_heat, mock_get_base_hot_dict,
mock_get_vnflcm_interface, mock_format_base_hot,
mock_get_scale_group, mock_create_stack_with_user_data):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
scaling_group=True, flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
s_status = {'aspect_id': 'VDU1_scale', 'scale_level': 1}
vnf['scale_status'] = [objects.ScaleInfo(**s_status)]
vnf_package_path_test = self._nfv_sample(
'user_data_sample_normal_scaling')
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'parameters': {'vnf': 'test'}}
base_hot_dict = self._read_file(scale_input_file=True)
mock_get_base_hot_dict.return_value = (base_hot_dict, nested_hot_dict)
mock_get_scale_group.return_value = {
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
'num': 1, 'maxLevel': 2, 'initialNum': 1,
'initialLevel': 0, 'default': 1}}}
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
self.assertEqual(mock_create_stack_with_user_data.call_count, 1)
# Expect desired_capacity in base_hot_dict to be changed
# by specified scale_statue
(base_hot_dict['resources']['VDU1_scale']['properties']
['desired_capacity']) = 2
mock_create_stack_with_user_data.assert_called_with(
mock.ANY, mock.ANY, base_hot_dict, mock.ANY, mock.ANY
)
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._create_stack_with_user_data')
@mock.patch('tacker.tosca.utils.get_scale_group')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils._get_vnflcm_interface')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_normal_with_scaling_group_and_not_scale_status(
self, mock_OpenstackClients_heat, mock_get_base_hot_dict,
mock_get_vnflcm_interface, mock_format_base_hot,
mock_get_scale_group, mock_create_stack_with_user_data):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
scaling_group=True, flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
'user_data_sample_normal_scaling')
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'parameters': {'vnf': 'test'}}
base_hot_dict = self._read_file(scale_input_file=True)
mock_get_base_hot_dict.return_value = (base_hot_dict, nested_hot_dict)
mock_get_scale_group.return_value = {
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
'num': 1, 'maxLevel': 2, 'initialNum': 1,
'initialLevel': 0, 'default': 1}}}
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
self.assertEqual(mock_create_stack_with_user_data.call_count, 1)
# Expect desired_capacity in base_hot_dict to be unchanged
mock_create_stack_with_user_data.assert_called_with(
mock.ANY, mock.ANY, base_hot_dict, mock.ANY, mock.ANY
)
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils._get_vnflcm_interface')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._update_stack_with_user_data')
@mock.patch.object(hc.HeatClient, "find_stack")
def test_create_normal_with_error_point_post_vim_control(
self, mock_find_stack, mock_update_stack_with_user_data,
mock_OpenstackClients_heat, mock_get_base_hot_dict,
mock_get_vnflcm_interface, mock_format_base_hot):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.POST_VIM_CONTROL
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
mock_find_stack.assert_called_once()
mock_update_stack_with_user_data.assert_called_once()
@mock.patch('tacker.tosca.utils.get_scale_group')
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_grant(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_format_base_hot,
mock_get_vim, mock_get_scale_group):
mock_get_scale_group.return_value = {
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
'num': 1, 'maxLevel': 2, 'initialNum': 1,
'initialLevel': 0, 'default': 1}}}
mock_get_vim.return_value = {
'vim_id': uuidsentinel.vnfd_id,
'vim_type': 'test',
'vim_auth': {'username': 'test', 'password': 'test'},
'placement_attr': {'region': 'TestRegionOne'},
'tenant': 'test'
}
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'VDU1.yaml': self._read_nested_file()}
base_hot_dict = self._read_file()
base_hot_dict['resources'].setdefault(
'VDU1_scale',
{'properties': {'resource':
{'properties': {'zone': {
'get_param': ['nfv', 'VDU', 'VDU1', 'zone']}},
'type': 'VDU1.yaml'}},
'type': 'OS::Heat::AutoScalingGroup'})
mock_get_base_hot_dict.return_value = \
base_hot_dict, nested_hot_dict
vim_assets = {
'compute_resource_flavours': [
{'vim_connection_id': uuidsentinel.vim_id,
'vnfd_virtual_compute_desc_id': 'VDU1',
'vim_flavour_id': 'm1.tiny'}],
'softwareImages': [
{'vim_connection_id': uuidsentinel.vim_id,
'vnfd_software_image_id': 'VDU1',
'vim_software_image_id': 'cirros'
}
]}
res_add_resource = []
resource = {
'resource_definition_id': '2c6e5cc7-240d-4458-a683-1fe648351280',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
resource = {
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa9',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
resource = {
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa0',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
resource = {
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa1',
'vim_connection_id': uuidsentinel.vim_id,
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
res_add_resource.append(resource)
zone = {
'id': '5e4da3c3-4a55-412a-b624-843921f8b51d',
'zone_id': 'nova',
'vim_connection_id': uuidsentinel.vim_id}
vim_obj = {
'id': '0b9c66bb-9e1f-4bb2-92c3-913074e52e2b',
'vim_id': uuidsentinel.vim_id,
'vim_type': 'openstack',
'access_info': {
'password': 'test_pw',
'username': 'test_user',
'region': 'test_region',
'tenant': uuidsentinel.tenant}}
grant_dict = {}
grant_dict['id'] = 'c213e465-8220-487e-9464-f79104e81e96'
grant_dict['vnf_instance_id'] = uuidsentinel.vnf_instance_id
grant_dict['vnf_lcm_op_occ_id'] = uuidsentinel.vnf_lcm_op_occ_id
grant_dict['add_resources'] = []
grant_dict['add_resources'].extend(res_add_resource)
grant_dict['vim_assets'] = vim_assets
grant_dict['zones'] = [zone]
grant_dict['vim_connections'] = [vim_obj]
grant_obj = objects.Grant.obj_from_primitive(
grant_dict, context=self.context)
vnf['grant'] = grant_obj
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_instance.instantiated_vnf_info.reinitialize()
vnfc_obj = objects.VnfcResourceInfo()
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
vnfc_obj.vdu_id = 'VDU1'
vnfc_obj.storage_resource_ids = (
['faf14707-da7c-4eec-be99-8099fa1e9fa0'])
compute_resource = objects.ResourceHandle(
vim_connection_id=uuidsentinel.vim_id,
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
vnfc_obj.compute_resource = compute_resource
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.tosca.utils.get_scale_group')
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_grant_scale(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_format_base_hot,
mock_get_vim, mock_get_scale_group):
mock_get_scale_group.return_value = {
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
'num': 1, 'maxLevel': 2, 'initialNum': 1,
'initialLevel': 0, 'default': 1}}}
mock_get_vim.return_value = {
'vim_id': uuidsentinel.vnfd_id,
'vim_type': 'test',
'vim_auth': {'username': 'test', 'password': 'test'},
'placement_attr': {'region': 'TestRegionOne'},
'tenant': 'test'
}
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'VDU1.yaml': self._read_nested_file()}
del nested_hot_dict['VDU1.yaml']['parameters']['zone']
del (nested_hot_dict['VDU1.yaml']['resources']
['VDU1']['properties']['availability_zone'])
base_hot_dict = self._read_file()
base_hot_dict['resources'].setdefault(
'VDU1_scale',
{'properties': {'resource':
{'properties': {},
'type': 'VDU1.yaml'}},
'type': 'OS::Heat::AutoScalingGroup'})
mock_get_base_hot_dict.return_value = \
base_hot_dict, nested_hot_dict
grant_dict = self._get_grant_obj(zoneid=True)
grant_obj = objects.Grant.obj_from_primitive(
grant_dict, context=self.context)
vnf['grant'] = grant_obj
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_instance.instantiated_vnf_info.reinitialize()
vnfc_obj = objects.VnfcResourceInfo()
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
vnfc_obj.vdu_id = 'VDU1'
vnfc_obj.storage_resource_ids = (
['faf14707-da7c-4eec-be99-8099fa1e9fa0'])
compute_resource = objects.ResourceHandle(
vim_connection_id=uuidsentinel.vim_id,
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
vnfc_obj.compute_resource = compute_resource
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.tosca.utils.get_scale_group')
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_grant_scale_vdu_nolist(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_format_base_hot,
mock_get_vim, mock_get_scale_group):
mock_get_scale_group.return_value = {
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDUX'],
'num': 1, 'maxLevel': 2, 'initialNum': 1,
'initialLevel': 0, 'default': 1}}}
mock_get_vim.return_value = {
'vim_id': uuidsentinel.vnfd_id,
'vim_type': 'test',
'vim_auth': {'username': 'test', 'password': 'test'},
'placement_attr': {'region': 'TestRegionOne'},
'tenant': 'test'
}
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'VDU1.yaml': self._read_nested_file()}
del nested_hot_dict['VDU1.yaml']['parameters']['zone']
del (nested_hot_dict['VDU1.yaml']['resources']
['VDU1']['properties']['availability_zone'])
base_hot_dict = self._read_file()
base_hot_dict['resources'].setdefault(
'VDU1_scale',
{'properties': {'resource':
{'properties': {},
'type': 'VDU1.yaml'}},
'type': 'OS::Heat::AutoScalingGroup'})
mock_get_base_hot_dict.return_value = \
base_hot_dict, nested_hot_dict
grant_dict = self._get_grant_obj(zoneid=True)
grant_obj = objects.Grant.obj_from_primitive(
grant_dict, context=self.context)
vnf['grant'] = grant_obj
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_instance.instantiated_vnf_info.reinitialize()
vnfc_obj = objects.VnfcResourceInfo()
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
vnfc_obj.vdu_id = 'VDU1'
vnfc_obj.storage_resource_ids = (
['faf14707-da7c-4eec-be99-8099fa1e9fa0'])
compute_resource = objects.ResourceHandle(
vim_connection_id=uuidsentinel.vim_id,
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
vnfc_obj.compute_resource = compute_resource
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_grant_scale_none(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_format_base_hot,
mock_get_vim):
mock_get_vim.return_value = {
'vim_id': uuidsentinel.vnfd_id,
'vim_type': 'test',
'vim_auth': {'username': 'test', 'password': 'test'},
'placement_attr': {'region': 'TestRegionOne'},
'tenant': 'test'
}
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'VDU1.yaml': self._read_nested_file()}
base_hot_dict = self._read_file()
base_hot_dict['resources'].setdefault(
'VDU1',
{'properties': {'resource':
{'properties': {'zone': {
'get_param': ['nfv', 'VDU', 'VDU1', 'zone']}},
'type': 'VDU1.yaml'}},
'type': 'OS::Heat::AutoScalingGroup'})
mock_get_base_hot_dict.return_value = \
base_hot_dict, nested_hot_dict
grant_dict = self._get_grant_obj(zoneid=True)
grant_obj = objects.Grant.obj_from_primitive(
grant_dict, context=self.context)
vnf['grant'] = grant_obj
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_instance.instantiated_vnf_info.reinitialize()
vnfc_obj = objects.VnfcResourceInfo()
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
vnfc_obj.vdu_id = 'VDU1'
vnfc_obj.storage_resource_ids = (
['faf14707-da7c-4eec-be99-8099fa1e9fa0'])
compute_resource = objects.ResourceHandle(
vim_connection_id=uuidsentinel.vim_id,
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
vnfc_obj.compute_resource = compute_resource
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.tosca.utils.get_scale_group')
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_grant_zone_add(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_format_base_hot,
mock_get_vim, mock_get_scale_group):
mock_get_scale_group.return_value = {
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
'num': 1, 'maxLevel': 2, 'initialNum': 1,
'initialLevel': 0, 'default': 1}}}
mock_get_vim.return_value = {
'vim_id': uuidsentinel.vnfd_id,
'vim_type': 'test',
'vim_auth': {'username': 'test', 'password': 'test'},
'placement_attr': {'region': 'TestRegionOne'},
'tenant': 'test'
}
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'VDU1.yaml': self._read_nested_file()}
del nested_hot_dict['VDU1.yaml']['parameters']['zone']
del (nested_hot_dict['VDU1.yaml']['resources']['VDU1']
['properties']['availability_zone'])
base_hot_dict = self._read_file()
base_hot_dict['resources'].setdefault(
'VDU1_scale',
{'properties': {'resource':
{'properties': {},
'type': 'VDU1.yaml'}},
'type': 'OS::Heat::AutoScalingGroup'})
mock_get_base_hot_dict.return_value = \
base_hot_dict, nested_hot_dict
grant_dict = self._get_grant_obj(zoneid=True)
grant_obj = objects.Grant.obj_from_primitive(
grant_dict, context=self.context)
vnf['grant'] = grant_obj
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_instance.instantiated_vnf_info.reinitialize()
vnfc_obj = objects.VnfcResourceInfo()
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
vnfc_obj.vdu_id = 'VDU1'
vnfc_obj.storage_resource_ids = (
['faf14707-da7c-4eec-be99-8099fa1e9fa0'])
compute_resource = objects.ResourceHandle(
vim_connection_id=uuidsentinel.vim_id,
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
vnfc_obj.compute_resource = compute_resource
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.tosca.utils.get_scale_group')
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_grant_zone_id_none(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict,
mock_format_base_hot,
mock_get_vim, mock_get_scale_group):
mock_get_scale_group.return_value = {
'scaleGroupDict': {'VDU1_scale': {'vdu': ['VDU1'],
'num': 1, 'maxLevel': 2, 'initialNum': 1,
'initialLevel': 0, 'default': 1}}}
mock_get_vim.return_value = {
'vim_id': uuidsentinel.vnfd_id,
'vim_type': 'test',
'vim_auth': {'username': 'test', 'password': 'test'},
'placement_attr': {'region': 'TestRegionOne'},
'tenant': 'test'
}
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'VDU1.yaml': self._read_nested_file()}
del nested_hot_dict['VDU1.yaml']['parameters']['zone']
del (nested_hot_dict['VDU1.yaml']['resources']['VDU1']
['properties']['availability_zone'])
base_hot_dict = self._read_file()
base_hot_dict['resources'].setdefault(
'VDU1_scale',
{'properties':
{'resource':
{'properties': {},
'type': 'VDU1.yaml'}},
'type': 'OS::Heat::AutoScali:ngGroup'})
mock_get_base_hot_dict.return_value = \
base_hot_dict, nested_hot_dict
grant_dict = self._get_grant_obj()
grant_obj = objects.Grant.obj_from_primitive(
grant_dict, context=self.context)
vnf['grant'] = grant_obj
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_instance.instantiated_vnf_info.reinitialize()
vnfc_obj = objects.VnfcResourceInfo()
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
vnfc_obj.vdu_id = 'VDU1'
vnfc_obj.storage_resource_ids = (
['faf14707-da7c-4eec-be99-8099fa1e9fa0'])
compute_resource = objects.ResourceHandle(
vim_connection_id=uuidsentinel.vim_id,
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
vnfc_obj.compute_resource = compute_resource
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_vnfd_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_heat_stack(self, mock_OpenstackClients_heat,
mock_vnfd_dict):
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path = None
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
mock_vnfd_dict.return_value = fakes.vnfd_dict_cnf()
vnf_instance = fd_utils.get_vnf_instance_object()
inst_req_info = fd_utils.get_instantiate_vnf_request()
self.assertIsNone(vnf.get('scale_status', None))
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, vnf_package_path, inst_req_info=inst_req_info,
grant_info=None, vnf_instance=vnf_instance)
self.assertIsNotNone(vnf.get('scale_status', None))
@mock.patch('tacker.vnflcm.utils.get_vnfd_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._update_stack')
@mock.patch.object(hc.HeatClient, "find_stack")
def test_create_heat_stack_with_error_point_post_vim_control(self,
mock_find_stack, mock_update_stack,
mock_OpenstackClients_heat, mock_vnfd_dict):
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path = None
vnf['before_error_point'] = fields.ErrorPoint.POST_VIM_CONTROL
mock_vnfd_dict.return_value = fakes.vnfd_dict_cnf()
vnf_instance = fd_utils.get_vnf_instance_object()
inst_req_info = fd_utils.get_instantiate_vnf_request()
self.assertIsNone(vnf.get('scale_status', None))
self.openstack.create(self.plugin, self.context, vnf,
self.auth_attr, vnf_package_path, inst_req_info=inst_req_info,
grant_info=None, vnf_instance=vnf_instance)
mock_find_stack.assert_called_once()
mock_update_stack.assert_called_once()
self.assertIsNotNone(vnf.get('scale_status', None))
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_userdata_none(self, mock_OpenstackClients_heat):
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# delete lcm-operation-user-data from additionalParams
del test_json['additionalParams']['lcm-operation-user-data']
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
grant_info_test = None
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test)
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_userdataclass_none(self, mock_OpenstackClients_heat):
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# delete lcm-operation-user-data-class from additionalParams
del test_json['additionalParams']['lcm-operation-user-data-class']
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
grant_info_test = None
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_userdata_null(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# set null to setlcm-operation-user-data from additionalParams
test_json['additionalParams']['lcm-operation-user-data'] = ''
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
grant_info_test = None
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_userdataclass_null(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# set null to setlcm-operation-user-data-class from additionalParams
test_json['additionalParams']['lcm-operation-user-data-class'] = ''
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
grant_info_test = None
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_import_module_exception(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
grant_info_test = None
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
with mock.patch.object(importlib, 'import_module') as mock_importlib:
mock_importlib.side_effect = Exception('Test Exception')
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_getattr_none(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample("user_data_sample_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = test_json['flavourId']
grant_info_test = None
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
with mock.patch.object(importlib, 'import_module') as mock_importlib:
mock_importlib.return_value = None
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_missing_file(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_none")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_return_none_dict(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_non_dict")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
test_json['additionalParams']['lcm-operation-user-data'] = \
'UserData/lcm_user_data_non_dict.py'
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_none_base_hot_dict(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.flavour_id = test_json['flavourId']
vnf_package_path_test = None
grant_info_test = None
nested_hot_dict = {}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_invalid_user_data(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# set dummy to setlcm-operation-user-data-class from additionalParams
test_json['additionalParams']['lcm-operation-user-data-class'] = \
'DummyUserData'
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
grant_info_test = None
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_invalid_user_data_class(self,
mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# set dummy to setlcm-operation-user-data-class from additionalParams
test_json['additionalParams']['lcm-operation-user-data-class'] = \
'DummyUserData'
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
grant_info_test = None
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path_test,
inst_req_info=inst_req_info_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_lcm_user_data_and_user_data_class_no_value(self,
mock_OpenstackClients_heat, mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# set null to setlcm-operation-user-data and
# lcm-operation-user-data-class from additionalParams
test_json['additionalParams']['lcm-operation-user-data'] = ''
test_json['additionalParams']['lcm-operation-user-data-class'] = ''
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = test_json['extVirtualLinks']
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_lcm_user_data_and_user_data_class_none(self,
mock_OpenstackClients_heat):
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_normal")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
# delete lcm-operation-user-data and
# lcm-operation-user-data-class from additionalParams
del test_json['additionalParams']['lcm-operation-user-data']
del test_json['additionalParams']['lcm-operation-user-data-class']
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = test_json['extVirtualLinks']
self.assertRaises(BaseException,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path=vnf_package_path_test,
inst_req_info=inst_req_info_test)
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_no_additionalparams(self, mock_OpenstackClients_heat):
vnf = utils.get_dummy_vnf(instance_id=self.instance_uuid)
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_normal")
vnf['placement_attr'] = {'region_name': 'dummy_region'}
inst_req_info_test = type('', (), {})
inst_req_info_test.additional_params = None
inst_req_info_test.ext_virtual_links = None
self.assertRaises(BaseException,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
vnf_package_path=vnf_package_path_test,
inst_req_info=inst_req_info_test)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients')
def test_create_instance_exception(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict):
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'}
vnf_package_path_test = self._nfv_sample(
"user_data_sample_userdata_invalid_script")
inst_req_info_test = type('', (), {})
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
test_json['additionalParams']['lcm-operation-user-data'] = \
'UserData/lcm_user_data_invalid_script.py'
inst_req_info_test.additional_params = test_json['additionalParams']
inst_req_info_test.ext_virtual_links = None
inst_req_info_test.flavour_id = 'simple'
vnf_resource = type('', (), {})
vnf_resource.resource_identifier = constants.INVALID_UUID
grant_info_test = {'vdu_name': {vnf_resource}}
nested_hot_dict = {'test': 'test'}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
vnf_instance = fd_utils.get_vnf_instance_object()
vnf['before_error_point'] = fields.ErrorPoint.PRE_VIM_CONTROL
self.assertRaises(vnfm.LCMUserDataFailed,
self.openstack.create,
self.plugin, self.context, vnf,
self.auth_attr,
inst_req_info=inst_req_info_test,
vnf_package_path=vnf_package_path_test,
grant_info=grant_info_test,
vnf_instance=vnf_instance)
def test_create_wait(self):
self._response_in_wait_until_stack_ready(["CREATE_IN_PROGRESS",
"CREATE_COMPLETE"])
vnf_dict = utils.get_dummy_vnf(instance_id=self.instance_uuid)
self.openstack.create_wait(None, None,
vnf_dict, self.instance_uuid, None)
self.mock_log.debug.assert_called_with('outputs %s',
fd_utils.get_dummy_stack()['outputs'])
self.assertEqual(bytes('{"VDU1": "192.168.120.216"}', 'utf-8'),
vnf_dict['mgmt_ip_address'])
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._wait_until_stack_ready')
def test_update_stack_wait(self, mock_wait_until_stack_ready):
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS",
"UPDATE_COMPLETE"])
vnf_dict = utils.get_dummy_vnf(instance_id=self.instance_uuid)
self.openstack.update_stack_wait(None, None,
vnf_dict, self.instance_uuid, None)
mock_wait_until_stack_ready.assert_called_once()
def test_create_wait_without_mgmt_ips(self):
self._response_in_wait_until_stack_ready(["CREATE_IN_PROGRESS",
"CREATE_COMPLETE"],
stack_outputs=False)
vnf_dict = utils.get_dummy_vnf(instance_id=self.instance_uuid)
self.openstack.create_wait(None, None,
vnf_dict, self.instance_uuid, None)
self.mock_log.debug.assert_called_with('outputs %s',
fd_utils.get_dummy_stack(outputs=False)['outputs'])
self.assertIsNone(vnf_dict['mgmt_ip_address'])
def test_create_wait_with_scaling_group_names(self):
self._response_in_wait_until_stack_ready(["CREATE_IN_PROGRESS",
"CREATE_COMPLETE"])
self._response_in_resource_get(self.instance_uuid,
res_name='SP1_group')
url = self.heat_url + '/stacks/' + self.stack_id + '/resources'
json = {'resources': [fd_utils.get_dummy_resource()]}
self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
self._response_in_resource_get(self.stack_id)
vnf_dict = utils.get_dummy_vnf(scaling_group=True)
self.openstack.create_wait(None, None, vnf_dict, self.instance_uuid,
None)
self.assertEqual(bytes('{"vdu1": ["test1"]}', 'utf-8'),
vnf_dict['mgmt_ip_address'])
def test_create_wait_failed_with_stack_retries_0(self):
self._response_in_wait_until_stack_ready(["CREATE_IN_PROGRESS"])
vnf_dict = utils.get_dummy_vnf(instance_id=self.instance_uuid)
self.assertRaises(vnfm.VNFCreateWaitFailed,
self.openstack.create_wait,
None, None, vnf_dict, self.instance_uuid, None)
def test_create_wait_failed_with_stack_retries_not_0(self):
self._response_in_wait_until_stack_ready(["CREATE_IN_PROGRESS",
"FAILED"])
vnf_dict = utils.get_dummy_vnf(instance_id=self.instance_uuid)
self.assertRaises(vnfm.VNFCreateWaitFailed,
self.openstack.create_wait,
None, None, vnf_dict, self.instance_uuid, {})
def _exception_response(self):
url = self.heat_url + '/stacks/' + self.instance_uuid
body = {"error": Exception("any stuff")}
self.requests_mock.register_uri('GET', url, body=body,
status_code=404, headers=self.json_headers)
def test_create_wait_with_exception(self):
self._exception_response()
vnf_dict = utils.get_dummy_vnf(instance_id=self.instance_uuid)
self.assertRaises(vnfm.VNFCreateWaitFailed,
self.openstack.create_wait,
None, None, vnf_dict, self.instance_uuid, None)
def test_delete_wait_failed_with_stack_retries_0(self):
self._response_in_wait_until_stack_ready(["DELETE_IN_PROGRESS"])
self.assertRaises(vnfm.VNFDeleteWaitFailed,
self.openstack.delete_wait,
None, None, self.instance_uuid, None, None)
def test_delete_wait_stack_retries_not_0(self):
self._response_in_wait_until_stack_ready(["DELETE_IN_PROGRESS",
"FAILED"])
self.assertRaises(vnfm.VNFDeleteWaitFailed,
self.openstack.delete_wait,
None, None, self.instance_uuid, None, None)
self.mock_log.error.assert_called_once()
def test_update_wait(self):
self._response_in_wait_until_stack_ready(["CREATE_COMPLETE"])
vnf_dict = utils.get_dummy_vnf(status='PENDING_UPDATE',
instance_id=self.instance_uuid)
self.openstack.update_wait(None, None, vnf_dict, None)
self.mock_log.debug.assert_called_with('outputs %s',
fd_utils.get_dummy_stack()['outputs'])
self.assertEqual(bytes('{"VDU1": "192.168.120.216"}', 'utf-8'),
vnf_dict['mgmt_ip_address'])
def test_heal_wait(self):
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS",
"UPDATE_COMPLETE"])
vnf_dict = utils.get_dummy_vnf(status='PENDING_HEAL',
instance_id=self.instance_uuid)
self.openstack.heal_wait(None, None, vnf_dict, None)
self.mock_log.debug.assert_called_with('outputs %s',
fd_utils.get_dummy_stack()['outputs'])
self.assertEqual(bytes('{"VDU1": "192.168.120.216"}', 'utf-8'),
vnf_dict['mgmt_ip_address'])
def test_heal_wait_without_mgmt_ips(self):
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS",
"UPDATE_COMPLETE"],
stack_outputs=False)
vnf_dict = utils.get_dummy_vnf(status='PENDING_HEAL',
instance_id=self.instance_uuid)
self.openstack.heal_wait(None, None, vnf_dict, None)
self.mock_log.debug.assert_called_with('outputs %s',
fd_utils.get_dummy_stack(outputs=False)['outputs'])
self.assertIsNone(vnf_dict['mgmt_ip_address'])
def test_heal_wait_failed_with_retries_0(self):
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS"])
vnf_dict = utils.get_dummy_vnf(status='PENDING_HEAL',
instance_id=self.instance_uuid)
self.assertRaises(vnfm.VNFHealWaitFailed,
self.openstack.heal_wait,
None, None, vnf_dict,
None)
def test_heal_wait_failed_stack_retries_not_0(self):
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS",
"FAILED"])
vnf_dict = utils.get_dummy_vnf(status='PENDING_HEAL',
instance_id=self.instance_uuid)
self.assertRaises(vnfm.VNFHealWaitFailed,
self.openstack.heal_wait,
None, None, vnf_dict,
None)
def _responses_in_resource_event_list(self, dummy_event):
# response for heat_client's resource_event_list()
url = self.heat_url + '/stacks/' + self.instance_uuid
json = {'stack': [fd_utils.get_dummy_stack()]}
self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
url = self.heat_url + '/stacks/' + self.instance_uuid + (
'/myStack/60f83b5e/resources/SP1_scale_out/events?limit=1&sort_dir'
'=desc&sort_keys=event_time')
json = {'events': [dummy_event]}
self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
@mock.patch('time.sleep')
@mock.patch('oslo_utils.timeutils.utcnow')
@mock.patch.object(hc.HeatClient, 'resource_metadata')
def test_scale(self,
mock_resource_metadata,
mock_utcnow,
mock_sleep):
mock_resource_metadata.return_value = {}
mock_utcnow.return_value = timeutils.parse_strtime(
'2000-01-01T00:00:00.000000')
dummy_event = fd_utils.get_dummy_event()
self._responses_in_resource_event_list(dummy_event)
# response for heat_client's resource_signal()
url = self.heat_url + '/stacks/' + self.instance_uuid + (
'/myStack/60f83b5e/resources/SP1_scale_out/signal')
self.requests_mock.register_uri('POST', url, json={},
headers=self.json_headers)
event_id = self.openstack.scale(plugin=self, context=self.context,
auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None)
mock_sleep.assert_not_called()
self.assertEqual(dummy_event['id'], event_id)
@mock.patch('time.sleep')
@mock.patch('oslo_utils.timeutils.utcnow')
@mock.patch.object(hc.HeatClient, 'resource_metadata')
def test_scale_cooldown(self,
mock_resource_metadata,
mock_utcnow,
mock_sleep):
"""A case where cooldown hasn't ended"""
mock_resource_metadata.return_value = {'cooldown_end':
{'2000-01-01T00:00:01.000000':
'cooldown_reason'},
'scaling_in_progress': 'false'}
mock_utcnow.return_value = timeutils.parse_strtime(
'2000-01-01T00:00:00.000000')
dummy_event = fd_utils.get_dummy_event()
self._responses_in_resource_event_list(dummy_event)
# response for heat_client's resource_signal()
url = self.heat_url + '/stacks/' + self.instance_uuid + (
'/myStack/60f83b5e/resources/SP1_scale_out/signal')
self.requests_mock.register_uri('POST', url, json={},
headers=self.json_headers)
event_id = self.openstack.scale(plugin=self, context=self.context,
auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None)
mock_sleep.assert_called_once_with(1)
self.assertEqual(dummy_event['id'], event_id)
@mock.patch('time.sleep')
@mock.patch('oslo_utils.timeutils.utcnow')
@mock.patch.object(hc.HeatClient, 'resource_metadata')
def test_scale_cooldown_ended(self,
mock_resource_metadata,
mock_utcnow,
mock_sleep):
"""A case where cooldown has already ended"""
mock_resource_metadata.return_value = {'cooldown_end':
{'2000-01-01T00:00:00.000000':
'cooldown_reason'},
'scaling_in_progress': 'false'}
mock_utcnow.return_value = timeutils.parse_strtime(
'2000-01-01T00:00:01.000000')
dummy_event = fd_utils.get_dummy_event()
self._responses_in_resource_event_list(dummy_event)
# response for heat_client's resource_signal()
url = self.heat_url + '/stacks/' + self.instance_uuid + (
'/myStack/60f83b5e/resources/SP1_scale_out/signal')
self.requests_mock.register_uri('POST', url, json={},
headers=self.json_headers)
event_id = self.openstack.scale(plugin=self, context=self.context,
auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None)
mock_sleep.assert_not_called()
self.assertEqual(dummy_event['id'], event_id)
def _response_in_resource_get_list(self, stack_id=None,
resources=None):
# response for heat_client's resource_get_list()
if stack_id:
url = self.heat_url + '/stacks/' + stack_id + '/resources'
else:
url = self.heat_url + '/stacks/' + self.stack_id + '/resources'
resources = resources or [fd_utils.get_dummy_resource()]
json = {'resources': resources}
self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
def _test_scale(self, resource_status):
dummy_event = fd_utils.get_dummy_event(resource_status)
self._responses_in_resource_event_list(dummy_event)
self._response_in_resource_get(self.instance_uuid, res_name='G1')
self._response_in_resource_get_list()
self._response_in_resource_get(self.stack_id)
self._response_in_resource_get(self.instance_uuid,
res_name='SP1_group')
@mock.patch.object(hc.HeatClient, "resource_event_list")
def test_scale_wait_with_different_last_event_id(self,
mock_resource_event_list):
self._test_scale("SIGNAL_COMPLETE")
print("test_scale_wait_with_different_last_event_id")
dummy_event = fd_utils.get_dummy_event("CREATE_IN_PROGRESS")
self._responses_in_resource_event_list(dummy_event)
event_list_obj = mock.MagicMock(id="fake")
fake_list = [event_list_obj]
mock_resource_event_list.return_value = fake_list
mgmt_ip = self.openstack.scale_wait(plugin=self, context=self.context,
auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None,
last_event_id=uuidsentinel.
non_last_event_id)
self.assertEqual(bytes('{"vdu1": ["test1"]}', 'utf-8'), mgmt_ip)
@mock.patch.object(hc.HeatClient, "resource_event_list")
@ddt.data("SIGNAL_COMPLETE", "CREATE_COMPLETE")
def test_scale_wait_with_same_last_event_id(self,
resource_status, mock_resource_event_list):
self._test_scale(resource_status)
event_list_obj = mock.MagicMock(id="fake")
fake_list = [event_list_obj]
mock_resource_event_list.return_value = fake_list
print("test_scale_wait_with_same_last_event_id")
mgmt_ip = self.openstack.scale_wait(plugin=self,
context=self.context,
auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None,
last_event_id=fd_utils.get_dummy_event()['id'])
self.assertEqual(bytes('{"vdu1": ["test1"]}', 'utf-8'), mgmt_ip)
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack.LOG')
def test_scale_wait_failed_with_exception(self, mock_log):
self._response_in_resource_get(self.instance_uuid)
url = self.heat_url + '/stacks/' + self.instance_uuid + '/resources'
body = {"error": Exception("any stuff")}
self.requests_mock.register_uri('GET', url, body=body,
status_code=404, headers=self.json_headers)
self._response_in_resource_get(self.instance_uuid,
res_name='SP1_group')
print("test_scale_wait_failed_with_exception")
self.assertRaises(vnfm.VNFScaleWaitFailed,
self.openstack.scale_wait,
plugin=self, context=self.context, auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None,
last_event_id=fd_utils.get_dummy_event()['id'])
mock_log.error.assert_called_once()
def _response_in_resource_metadata(self, metadata=None):
# response for heat_client's resource_metadata()
url = self.heat_url + '/stacks/' + self.instance_uuid + \
'/myStack/60f83b5e/resources/SP1_scale_out/metadata'
json = {'metadata': {'scaling_in_progress': metadata}}
return self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
def test_scale_wait_failed_with_stack_retries_0(self):
print("test_scale_wait_failed_with_stack_retries_0")
self._response_in_resource_get(self.instance_uuid)
self._response_in_resource_metadata(True)
self._response_in_resource_get(self.stack_id, res_name='G1')
self._response_in_resource_get_list(
resources=[fd_utils.get_dummy_resource(
resource_status="IN_PROGRESS")])
self._response_in_resource_get(self.stack_id)
self._response_in_resource_get(self.instance_uuid,
res_name='SP1_group')
self.assertRaises(vnfm.VNFScaleWaitFailed,
self.openstack.scale_wait,
plugin=self, context=self.context, auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None,
last_event_id=uuidsentinel.event_id)
self.mock_log.error.assert_called_once()
def test_scale_wait_without_resource_metadata(self):
dummy_event = fd_utils.get_dummy_event("CREATE_IN_PROGRESS")
self._responses_in_resource_event_list(dummy_event)
self._response_in_resource_metadata()
self._response_in_resource_get(self.instance_uuid, res_name='G1')
self._response_in_resource_get_list()
self._response_in_resource_get(self.stack_id)
self._response_in_resource_get(self.instance_uuid,
res_name='SP1_group')
mgmt_ip = self.openstack.scale_wait(plugin=self, context=self.context,
auth_attr=None,
policy=fd_utils.get_dummy_policy_dict(),
region_name=None,
last_event_id=fd_utils.get_dummy_event()
['id'])
error_reason = ('skip scaling')
self.mock_log.warning.assert_called_once_with(error_reason)
self.assertEqual(b'{"vdu1": ["test1"]}', mgmt_ip)
def _responses_in_create_image(self, multiple_responses=False):
# response for glance_client's create()
json = fd_utils.get_fake_glance_image_dict()
url = os.path.join(self.glance_url, 'images')
if multiple_responses:
return self.requests_mock.register_uri(
'POST', url, [{'json': json, 'status_code': 201,
'headers': self.json_headers},
{'exc': requests.exceptions.ConnectTimeout}])
else:
return self.requests_mock.register_uri('POST', url, json=json,
headers=self.json_headers)
def _responses_in_import_image(self, raise_exception=False):
# response for glance_client's import()
json = fd_utils.get_fake_glance_image_dict()
url = os.path.join(
self.glance_url, 'images', uuidsentinel.image_id, 'import')
if raise_exception:
return self.requests_mock.register_uri('POST', url,
exc=requests.exceptions.ConnectTimeout)
else:
return self.requests_mock.register_uri('POST', url, json=json,
headers=self.json_headers)
def _responses_in_get_image(self, image_path=None, status='active',
hash_value='hash'):
# response for glance_client's import()
json = fd_utils.get_fake_glance_image_dict(image_path=image_path,
status=status,
hash_value=hash_value)
url = os.path.join(
self.glance_url, 'images', uuidsentinel.image_id)
return self.requests_mock.register_uri('GET', url, json=json,
headers=self.json_headers)
def _responses_in_upload_image(self, image_path=None, status='active',
hash_value='hash'):
# response for glance_client's upload()
json = fd_utils.get_fake_glance_image_dict(image_path=image_path,
status=status,
hash_value=hash_value)
url = os.path.join(
self.glance_url, 'images', uuidsentinel.image_id, 'file')
return self.requests_mock.register_uri('PUT', url, json=json,
headers=self.json_headers)
def test_pre_instantiation_vnf_image_with_file(self):
vnf_instance = fd_utils.get_vnf_instance_object()
# Create a temporary file as the openstacksdk will access it for
# calculating the hash value.
image_fd, image_path = tempfile.mkstemp()
vnf_software_image = fd_utils.get_vnf_software_image_object(
image_path=image_path)
vnf_software_images = {'node_name': vnf_software_image}
upload_image_url = self._responses_in_upload_image(image_path)
create_image_url = self._responses_in_create_image()
get_image_url = self._responses_in_get_image(image_path)
vnf_resources = self.openstack.pre_instantiation_vnf(
self.context, vnf_instance, None, vnf_software_images)
image_resource = vnf_resources['node_name'][0]
os.close(image_fd)
os.remove(image_path)
# Asserting the response as per the data given in the fake objects.
self.assertEqual(image_resource.resource_name,
'test-image')
self.assertEqual(image_resource.resource_status,
'CREATED')
self.assertEqual(image_resource.resource_type,
'image')
self.assertEqual(image_resource.vnf_instance_id,
vnf_instance.id)
self.assertEqual(upload_image_url.call_count, 1)
self.assertEqual(create_image_url.call_count, 1)
self.assertTrue(get_image_url.call_count >= 1)
@mock.patch('tacker.common.utils.is_url', mock.MagicMock(
return_value=True))
def test_pre_instantiation_vnf_image_with_url(self):
image_path = "http://fake-url.net"
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_software_image = fd_utils.get_vnf_software_image_object(
image_path=image_path)
vnf_software_images = {'node_name': vnf_software_image}
create_image_url = self._responses_in_create_image(image_path)
import_image_url = self._responses_in_import_image()
get_image_url = self._responses_in_get_image(image_path)
vnf_resources = self.openstack.pre_instantiation_vnf(
self.context, vnf_instance, None, vnf_software_images)
image_resource = vnf_resources['node_name'][0]
# Asserting the response as per the data given in the fake objects.
self.assertEqual(image_resource.resource_name,
'test-image')
self.assertEqual(image_resource.resource_status,
'CREATED')
self.assertEqual(image_resource.resource_type,
'image')
self.assertEqual(image_resource.vnf_instance_id,
vnf_instance.id)
self.assertEqual(create_image_url.call_count, 1)
self.assertEqual(import_image_url.call_count, 1)
self.assertEqual(get_image_url.call_count, 1)
@ddt.data(False, True)
def test_pre_instantiation_vnf_failed_in_image_creation(
self, exception_in_delete_image):
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_software_image = fd_utils.get_vnf_software_image_object()
vnf_software_images = {'node_name1': vnf_software_image,
'node_name2': vnf_software_image}
# exception will occur in second iteration of image creation.
create_image_url = self._responses_in_create_image(
multiple_responses=True)
import_image_url = self._responses_in_import_image()
get_image_url = self._responses_in_get_image()
delete_image_url = self._response_in_delete_image(
uuidsentinel.image_id, exception=exception_in_delete_image)
self.assertRaises(exceptions.VnfPreInstantiationFailed,
self.openstack.pre_instantiation_vnf,
self.context, vnf_instance, None,
vnf_software_images)
self.assertEqual(create_image_url.call_count, 3)
self.assertEqual(import_image_url.call_count, 1)
self.assertEqual(get_image_url.call_count, 1)
delete_call_count = 2 if exception_in_delete_image else 1
self.assertEqual(delete_image_url.call_count, delete_call_count)
@ddt.data(False, True)
def test_pre_instantiation_vnf_failed_in_image_upload(
self, exception_in_delete_image):
vnf_instance = fd_utils.get_vnf_instance_object()
image_path = '/non/existent/file'
software_image_update = {'image_path': image_path}
vnf_software_image = fd_utils.get_vnf_software_image_object(
**software_image_update)
vnf_software_images = {'node_name1': vnf_software_image,
'node_name2': vnf_software_image}
# exception will occur in second iteration of image creation.
# No urls are accessed in this case because openstacksdk fails to
# access the file when it wants to calculate the hash.
self._responses_in_create_image(multiple_responses=True)
self._responses_in_upload_image(image_path)
self._responses_in_get_image()
self._response_in_delete_image(uuidsentinel.image_id,
exception=exception_in_delete_image)
self.assertRaises(exceptions.VnfPreInstantiationFailed,
self.openstack.pre_instantiation_vnf,
self.context, vnf_instance, None,
vnf_software_images)
def test_pre_instantiation_vnf_failed_with_mismatch_in_hash_value(self):
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_software_image = fd_utils.get_vnf_software_image_object()
vnf_software_images = {'node_name1': vnf_software_image,
'node_name2': vnf_software_image}
# exception will occur in second iteration of image creation.
create_image_url = self._responses_in_create_image(
multiple_responses=True)
import_image_url = self._responses_in_import_image()
get_image_url = self._responses_in_get_image(
hash_value='diff-hash-value')
delete_image_url = self._response_in_delete_image(
uuidsentinel.image_id)
self.assertRaises(exceptions.VnfPreInstantiationFailed,
self.openstack.pre_instantiation_vnf,
self.context, vnf_instance, None,
vnf_software_images)
self.assertEqual(create_image_url.call_count, 1)
self.assertEqual(import_image_url.call_count, 1)
self.assertEqual(get_image_url.call_count, 1)
self.assertEqual(delete_image_url.call_count, 1)
def test_pre_instantiation_vnf_with_image_create_wait_failed(self):
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_software_image = fd_utils.get_vnf_software_image_object()
vnf_software_images = {'node_name1': vnf_software_image,
'node_name2': vnf_software_image}
# exception will occurs in second iteration of image creation.
create_image_url = self._responses_in_create_image()
import_image_url = self._responses_in_import_image()
get_image_url = self._responses_in_get_image(status='pending_create')
self.assertRaises(exceptions.VnfPreInstantiationFailed,
self.openstack.pre_instantiation_vnf,
self.context, vnf_instance, None,
vnf_software_images)
self.assertEqual(create_image_url.call_count, 1)
self.assertEqual(import_image_url.call_count, 1)
self.assertEqual(get_image_url.call_count, 10)
def _response_in_delete_image(self, resource_id, exception=False):
# response for glance_client's delete()
url = os.path.join(
self.glance_url, 'images', resource_id)
if exception:
return self.requests_mock.register_uri(
'DELETE', url, exc=requests.exceptions.ConnectTimeout)
else:
return self.requests_mock.register_uri('DELETE', url, json={},
status_code=200,
headers=self.json_headers)
@ddt.data(True, False)
def test_pre_instantiation_vnf_failed_in_image_import(
self, exception_in_delete):
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_software_image = fd_utils.get_vnf_software_image_object()
vnf_software_images = {'node_name': vnf_software_image}
create_image_url = self._responses_in_create_image()
import_image_exc_url = self._responses_in_import_image(
raise_exception=True)
delete_image_url = self._response_in_delete_image(
uuidsentinel.image_id, exception_in_delete)
self.assertRaises(exceptions.VnfPreInstantiationFailed,
self.openstack.pre_instantiation_vnf,
self.context, vnf_instance, None,
vnf_software_images)
self.assertEqual(create_image_url.call_count, 1)
self.assertEqual(import_image_exc_url.call_count, 2)
delete_call_count = 2 if exception_in_delete else 1
self.assertEqual(delete_image_url.call_count, delete_call_count)
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack.LOG')
def test_delete_vnf_instance_resource(self, mock_log):
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_resource = fd_utils.get_vnf_resource_object()
delete_image_url = self._response_in_delete_image(
vnf_resource.resource_identifier)
self.openstack.delete_vnf_instance_resource(
self.context, vnf_instance, None, vnf_resource)
mock_log.info.assert_called()
self.assertEqual(delete_image_url.call_count, 1)
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack.LOG')
def test_delete_vnf_instance_resource_failed_with_exception(
self, mock_log):
vnf_instance = fd_utils.get_vnf_instance_object()
vnf_resource = fd_utils.get_vnf_resource_object()
delete_image_url = self._response_in_delete_image(
vnf_resource.resource_identifier, exception=True)
self.openstack.delete_vnf_instance_resource(
self.context, vnf_instance, None, vnf_resource)
mock_log.info.assert_called()
self.assertEqual(delete_image_url.call_count, 2)
@mock.patch('tacker.vnflcm.utils.get_vnfd_dict')
@mock.patch('tacker.vnfm.infra_drivers.openstack.translate_template.'
'TOSCAToHOT._get_unsupported_resource_props')
@mock.patch.object(hc.HeatClient, "find_stack")
def test_instantiate_vnf(self, mock_get_unsupported_resource_props,
mock_find_stack, mock_vnfd_dict):
vim_connection_info = fd_utils.get_vim_connection_info_object()
inst_req_info = fd_utils.get_instantiate_vnf_request()
grant_response = fd_utils.get_grant_response_dict()
url = os.path.join(self.heat_url, 'stacks')
self.requests_mock.register_uri(
'POST', url, json={'stack': fd_utils.get_dummy_stack()},
headers=self.json_headers)
vnf_instance = fd_utils.get_vnf_instance_object()
vnfd_dict = {
**fd_utils.get_vnfd_dict(),
'before_error_point': fields.ErrorPoint.PRE_VIM_CONTROL,
'status': ''
}
mock_vnfd_dict.return_value = fakes.vnfd_dict_cnf()
instance_id = self.openstack.instantiate_vnf(
self.context, vnf_instance, vnfd_dict, vim_connection_info,
inst_req_info, grant_response, self.plugin)
self.assertEqual(uuidsentinel.instance_id, instance_id)
def _responses_in_stack_list(self, instance_id, resources=None):
resources = resources or []
url = os.path.join(self.heat_url, 'stacks', instance_id, 'resources')
self.requests_mock.register_uri('GET', url,
json={'resources': resources}, headers=self.json_headers)
response_list = [{'json': {'stacks': [fd_utils.get_dummy_stack(
attrs={'parent': uuidsentinel.instance_id})]}},
{'json': {'stacks': [fd_utils.get_dummy_stack()]}}]
url = os.path.join(self.heat_url, 'stacks?owner_id=' +
instance_id + '&show_nested=True')
self.requests_mock.register_uri('GET', url, response_list)
def test_post_vnf_instantiation(self):
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vnf_instance.vnf_metadata = None
vim_connection_info = fd_utils.get_vim_connection_info_object()
resources = [{'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.vdu_resource_id},
{'resource_name': v_s_resource_info.virtual_storage_desc_id,
'resource_type': v_s_resource_info.storage_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.storage_resource_id},
{'resource_name': vnfc_resource_info.vnfc_cp_info[0].cpd_id,
'resource_type': inst_vnf_info.vnf_virtual_link_resource_info[0].
vnf_link_ports[0].resource_handle.vim_level_resource_type,
'physical_resource_id': uuidsentinel.cp1_resource_id}]
inst_req_info = fd_utils.get_instantiate_vnf_request()
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
self.openstack.post_vnf_instantiation(
self.context, vnf_instance, vim_connection_info, inst_req_info)
self.assertEqual(vnf_instance.instantiated_vnf_info.
vnfc_resource_info[0].metadata['stack_id'],
inst_vnf_info.instance_id)
# Check if vnfc resource "VDU_VNF" is set with resource_id
self.assertEqual(uuidsentinel.vdu_resource_id,
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].
compute_resource.resource_id)
# Check if virtual storage resource "storage1" is set with resource_id
self.assertEqual(uuidsentinel.storage_resource_id,
vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].storage_resource.resource_id)
# Check if virtual link port "CP1" is set with resource_id
self.assertEqual(uuidsentinel.cp1_resource_id,
vnf_instance.instantiated_vnf_info.
vnf_virtual_link_resource_info[0].vnf_link_ports[0].
resource_handle.resource_id)
# Check if tenant data is stored in vnf_metadata
self.assertEqual(vnf_instance.vnf_metadata['tenant'],
vim_connection_info.access_info['project_name'])
def test_post_vnf_instantiation_with_ext_managed_virtual_link(self):
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id,
desc_id='ExternalVL1')
ext_managed_v_l_resource_info = \
fd_utils.get_ext_managed_virtual_link_resource_info(
uuidsentinel.virtual_link_port_id,
uuidsentinel.vnfc_cp_info_id,
desc_id='ExternalVL1')
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info],
ext_managed_virtual_link_info=[ext_managed_v_l_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
resources = [{'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.vdu_resource_id},
{'resource_name': v_s_resource_info.virtual_storage_desc_id,
'resource_type': v_s_resource_info.storage_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.storage_resource_id},
{'resource_name': vnfc_resource_info.vnfc_cp_info[0].cpd_id,
'resource_type': inst_vnf_info.vnf_virtual_link_resource_info[0].
vnf_link_ports[0].resource_handle.vim_level_resource_type,
'physical_resource_id': uuidsentinel.cp1_resource_id},
{'resource_name': v_l_resource_info.vnf_virtual_link_desc_id,
'resource_type': v_l_resource_info.network_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.v_l_resource_info_id}]
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
inst_req_info = fd_utils.get_instantiate_vnf_request()
self.openstack.post_vnf_instantiation(
self.context, vnf_instance, vim_connection_info, inst_req_info)
self.assertEqual(vnf_instance.instantiated_vnf_info.
vnfc_resource_info[0].metadata['stack_id'],
inst_vnf_info.instance_id)
# Check if vnfc resource "VDU_VNF" is set with resource_id
self.assertEqual(uuidsentinel.vdu_resource_id,
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].
compute_resource.resource_id)
# Check if virtual storage resource "storage1" is set with resource_id
self.assertEqual(uuidsentinel.storage_resource_id,
vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].storage_resource.resource_id)
# Check if virtual link port "CP1" is set with resource_id
self.assertEqual(uuidsentinel.cp1_resource_id,
vnf_instance.instantiated_vnf_info.
vnf_virtual_link_resource_info[0].vnf_link_ports[0].
resource_handle.resource_id)
# Check if ext managed virtual link port is set with resource_id
self.assertEqual(uuidsentinel.cp1_resource_id,
vnf_instance.instantiated_vnf_info.
ext_managed_virtual_link_info[0].vnf_link_ports[0].
resource_handle.resource_id)
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.vnflcm.utils._get_vnf_package_path')
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_vnf_instance_id")
@mock.patch.object(hc.HeatClient, "find_stack")
def test_heal_vnf_instance(self, mock_find_stack,
mock_get_vnflcm_op_occs,
mock_get_vnf_package_path,
mock_get_base_hot_dict):
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1")
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnfc_resource_info=[vnfc_resource_info])
mock_get_vnf_package_path.return_value = self._nfv_sample(
"stack_update_in_heal")
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
heal_vnf_request = objects.HealVnfRequest(
vnfc_instance_id=[vnfc_resource_info.id],
cause="healing request")
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf.
resources = [{
'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': vnfc_resource_info.compute_resource.
resource_id}, {
'resource_name': v_s_resource_info.virtual_storage_desc_id,
'resource_type': v_s_resource_info.storage_resource.
vim_level_resource_type,
'physical_resource_id': v_s_resource_info.storage_resource.
resource_id}]
self._response_in_stack_get(inst_vnf_info.instance_id)
self._response_in_resource_get_list(inst_vnf_info.instance_id,
resources=resources)
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
self._response_in_stack_update(inst_vnf_info.instance_id)
self._response_resource_mark_unhealthy(inst_vnf_info.instance_id,
resources=resources)
vnf_lcm_op_occs = fd_utils.get_lcm_op_occs_object(
error_point=fields.ErrorPoint.PRE_VIM_CONTROL)
mock_get_vnflcm_op_occs.return_value = vnf_lcm_op_occs
self.openstack.heal_vnf(
self.context, vnf_instance, vim_connection_info,
heal_vnf_request)
history = self.requests_mock.request_history
patch_req = [req.url for req in history if req.method == 'PATCH']
# Total 3 times patch should be called, 2 for marking resources
# as unhealthy, and 1 for updating stack
self.assertEqual(3, len(patch_req))
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.vnflcm.utils._get_vnf_package_path')
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_vnf_instance_id")
def test_heal_stack_params(self, mock_get_vnflcm_op_occs,
mock_get_vnf_package_path,
mock_get_base_hot_dict):
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1")
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnfc_resource_info=[vnfc_resource_info])
test_json = self._json_load(
'instantiate_vnf_request_lcm_userdata.json')
inst_vnf_info.additional_params = test_json['additionalParams']
mock_get_vnf_package_path.return_value = self._nfv_sample(
"stack_update_in_heal")
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
heal_vnf_request = objects.HealVnfRequest(
vnfc_instance_id=[vnfc_resource_info.id],
cause="healing request")
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf.
resources = [{
'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': vnfc_resource_info.compute_resource.
resource_id}, {
'resource_name': v_s_resource_info.virtual_storage_desc_id,
'resource_type': v_s_resource_info.storage_resource.
vim_level_resource_type,
'physical_resource_id': v_s_resource_info.storage_resource.
resource_id}]
self._response_in_stack_get(inst_vnf_info.instance_id)
self._response_in_resource_get_list(inst_vnf_info.instance_id,
resources=resources)
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
self._response_in_stack_update(inst_vnf_info.instance_id)
self._response_resource_mark_unhealthy(inst_vnf_info.instance_id,
resources=resources)
vnf_lcm_op_occs = fd_utils.get_lcm_op_occs_object(
error_point=fields.ErrorPoint.PRE_VIM_CONTROL)
mock_get_vnflcm_op_occs.return_value = vnf_lcm_op_occs
self.openstack.heal_vnf(
self.context, vnf_instance, vim_connection_info,
heal_vnf_request)
history = self.requests_mock.request_history
patch_req = [req.url for req in history if req.method == 'PATCH']
# Total 3 times patch should be called, 2 for marking resources
# as unhealthy, and 1 for updating stack
self.assertEqual(3, len(patch_req))
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.vnflcm.utils._get_vnf_package_path')
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_vnf_instance_id")
def test_heal_vnf_instance_error_point_post_vim_control(
self, mock_get_vnflcm_op_occs, mock_get_vnf_package_path,
mock_get_base_hot_dict):
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = \
self._read_file(), nested_hot_dict
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1")
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnfc_resource_info=[vnfc_resource_info])
mock_get_vnf_package_path.return_value = self._nfv_sample(
"stack_update_in_heal")
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
heal_vnf_request = objects.HealVnfRequest(
vnfc_instance_id=[vnfc_resource_info.id],
cause="healing request")
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf.
resources = [{
'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': vnfc_resource_info.compute_resource.
resource_id}, {
'resource_name': v_s_resource_info.virtual_storage_desc_id,
'resource_type': v_s_resource_info.storage_resource.
vim_level_resource_type,
'physical_resource_id': v_s_resource_info.storage_resource.
resource_id}]
self._response_in_stack_get(inst_vnf_info.instance_id)
self._response_in_resource_get_list(inst_vnf_info.instance_id,
resources=resources)
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
self._response_in_stack_update(inst_vnf_info.instance_id)
vnf_lcm_op_occs = fd_utils.get_lcm_op_occs_object(
error_point=fields.ErrorPoint.POST_VIM_CONTROL)
mock_get_vnflcm_op_occs.return_value = vnf_lcm_op_occs
self.openstack.heal_vnf(
self.context, vnf_instance, vim_connection_info,
heal_vnf_request)
history = self.requests_mock.request_history
patch_req = [req.url for req in history if req.method == 'PATCH']
# Total of 1 times for updating stack
self.assertEqual(1, len(patch_req))
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_vnf_instance_id")
def test_heal_vnf_instance_resource_mark_unhealthy_error(
self, mock_get_vnflcm_op_occs, mock_get_base_hot_dict):
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF")
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
heal_vnf_request = objects.HealVnfRequest(
vnfc_instance_id=[vnfc_resource_info.id],
cause="healing request")
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = (
self._read_file(), nested_hot_dict)
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf.
resources = [{
'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': vnfc_resource_info.compute_resource.
resource_id}]
self._response_in_stack_get(inst_vnf_info.instance_id)
self._response_in_resource_get_list(inst_vnf_info.instance_id,
resources=resources)
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
self._response_resource_mark_unhealthy(inst_vnf_info.instance_id,
resources=resources, raise_exception=True)
vnf_lcm_op_occs = fd_utils.get_lcm_op_occs_object(
error_point=3)
mock_get_vnflcm_op_occs.return_value = vnf_lcm_op_occs
result = self.assertRaises(exceptions.VnfHealFailed,
self.openstack.heal_vnf, self.context, vnf_instance,
vim_connection_info, heal_vnf_request)
expected_msg = ("Failed to mark stack '%(id)s' resource as unhealthy "
"for resource '%(resource_name)s'") % {
'id': inst_vnf_info.instance_id,
'resource_name': resources[0]['resource_name']}
self.assertIn(expected_msg, str(result))
history = self.requests_mock.request_history
patch_req = [req.url for req in history if req.method == 'PATCH']
# only one time patch method be called for marking vdu resource
# as unhealthy
self.assertEqual(1, len(patch_req))
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch.object(objects.VnfLcmOpOcc, "get_by_vnf_instance_id")
def test_heal_vnf_instance_incorrect_stack_status(
self, mock_get_vnflcm_op_occs, mock_get_base_hot_dict):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
heal_vnf_request = objects.HealVnfRequest(
vnfc_instance_id=[uuidsentinel.vnfc_resource_id],
cause="healing request")
nested_hot_dict = {'parameters': {'vnf': 'test'}}
mock_get_base_hot_dict.return_value = (
self._read_file(), nested_hot_dict)
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf.
self._response_in_stack_get(inst_vnf_info.instance_id,
stack_status='UPDATE_IN_PROGRESS')
vnf_lcm_op_occs = fd_utils.get_lcm_op_occs_object(
error_point=3)
mock_get_vnflcm_op_occs.return_value = vnf_lcm_op_occs
result = self.assertRaises(exceptions.VnfHealFailed,
self.openstack.heal_vnf, self.context, vnf_instance,
vim_connection_info, heal_vnf_request)
expected_msg = ("Healing of vnf instance %s is possible only when "
"stack %s status is CREATE_COMPLETE,UPDATE_COMPLETE, "
"current stack status is UPDATE_IN_PROGRESS")
self.assertIn(expected_msg % (vnf_instance.id,
inst_vnf_info.instance_id), str(result))
def test_heal_vnf_wait(self):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf_wait.
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS",
"UPDATE_COMPLETE"])
stack = self.openstack.heal_vnf_wait(
self.context, vnf_instance, vim_connection_info, None)
self.assertEqual('UPDATE_COMPLETE', stack.stack_status)
def test_heal_vnf_wait_fail(self):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf_wait.
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS"])
self.openstack.STACK_RETRIES = 1
result = self.assertRaises(vnfm.VNFHealWaitFailed,
self.openstack.heal_vnf_wait, self.context, vnf_instance,
vim_connection_info, None)
expected_msg = ("VNF Heal action is not completed within 10 seconds "
"on stack %s") % inst_vnf_info.instance_id
self.assertIn(expected_msg, str(result))
def test_post_heal_vnf(self):
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1")
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnfc_resource_info.metadata['stack_id'] = inst_vnf_info.instance_id
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
heal_vnf_request = objects.HealVnfRequest(
vnfc_instance_id=[vnfc_resource_info.id],
cause="healing request")
# Change the physical_resource_id of both the resources, so
# that we can check it's updated in vnf instance after
# post_heal_vnf call.
resources = [{
'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.compute_resource_id_new}, {
'resource_name': v_s_resource_info.virtual_storage_desc_id,
'resource_type': v_s_resource_info.storage_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.storage_resource_id_new}]
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf.
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
v_s_resource_info_old = v_s_resource_info.obj_clone()
vnfc_resource_info_old = vnfc_resource_info.obj_clone()
self.openstack.post_heal_vnf(self.context, vnf_instance,
vim_connection_info, heal_vnf_request)
vnfc_resource_info_new = vnf_instance.instantiated_vnf_info.\
vnfc_resource_info[0]
v_s_resource_info_new = vnf_instance.instantiated_vnf_info.\
virtual_storage_resource_info[0]
# Compare the resource_id, it should be updated with the new ones.
self.assertNotEqual(vnfc_resource_info_old.compute_resource.
resource_id, vnfc_resource_info_new.compute_resource.resource_id)
self.assertEqual(uuidsentinel.compute_resource_id_new,
vnfc_resource_info_new.compute_resource.resource_id)
self.assertNotEqual(v_s_resource_info_old.storage_resource.resource_id,
v_s_resource_info_new.storage_resource.resource_id)
self.assertEqual(uuidsentinel.storage_resource_id_new,
v_s_resource_info_new.storage_resource.resource_id)
def test_post_heal_vnf_fail(self):
vnfc_resource_info = fd_utils.get_vnfc_resource_info()
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
vnfc_resource_info=[vnfc_resource_info])
vnfc_resource_info.metadata['stack_id'] = uuidsentinel.stack_id
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
heal_vnf_request = objects.HealVnfRequest(
vnfc_instance_id=[vnfc_resource_info.id],
cause="healing request")
# Change the physical_resource_id of both the resources, so
# that we can check it's updated in vnf instance after
# post_heal_vnf call.
resources = [{
'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.compute_resource_id_new}]
# Mock various heat APIs that will be called by heatclient
# during the process of heal_vnf.
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
result = self.assertRaises(exceptions.VnfHealFailed,
self.openstack.post_heal_vnf, self.context, vnf_instance,
vim_connection_info, heal_vnf_request)
expected_msg = ("Heal Vnf failed for vnf %s, error: Failed to find "
"stack_id %s") % (vnf_instance.id,
uuidsentinel.stack_id)
self.assertEqual(expected_msg, str(result))
def test_get_grant_resource_scale_out(self):
vnfc_resource_info = fd_utils.get_vnfc_resource_info()
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='SP1',
number_of_steps=1)
test_res = '[{"id_type": "RES_MGMT", "resource_id": ' + \
'"2c6e5cc7-240d-4458-a683-1fe648351200",' + \
' "vim_connection_id": ' + \
'"2a63bee3-0c43-4568-bcfa-b0cb733e064c"}]'
placemnt = models.PlacementConstraint(
id='c2947d8a-2c67-4e8f-ad6f-c0889b351c17',
vnf_instance_id=uuidsentinel.vnf_instance_id,
affinity_or_anti_affinity='ANTI_AFFINITY',
scope='NFVI_NODE',
server_group_name='my_compute_placement_policy',
resource=test_res)
placement_obj_list = [placemnt]
del_list = []
vnf_info = {}
vnf_info['attributes'] = {}
vnf_info['attributes']['scale_group'] = '{\"scaleGroupDict\": ' + \
'{ \"SP1\": { \"vdu\": [\"VDU1\"], \"num\": ' + \
'1, \"maxLevel\": 3, \"initialNum\": 0, ' + \
'\"initialLevel\": 0, \"default\": 0 }}}'
vnf_info['attributes']['heat_template'] = utils.\
get_dummy_scale_grant_hot()
vnf_info['attributes']['SP1_res.yaml'] = utils.\
get_dummy_scale_nest_grant_hot()
self.openstack.get_grant_resource(
self,
vnf_instance,
vnf_info,
scale_vnf_request,
placement_obj_list,
vim_connection_info,
del_list)
self.assertEqual(1, len(vnf_info['placement_constraint_list']))
self.assertEqual('NFVI_NODE',
vnf_info['placement_constraint_list'][0].scope)
@mock.patch.object(hc.HeatClient, "resource_get_list")
def test_get_grant_resource_scale_in(self, mock_list):
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_IN',
aspect_id='SP1',
number_of_steps=1)
placement_obj_list = []
del_list = ['58337c61-3148-4c29-892f-68b043c009ea']
vnf_info = {}
res_list = []
vdu_id = uuidsentinel.vdu_resource_id
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].\
compute_resource.resource_id = vdu_id
resource2 = resources.Resource(None, {
'resource_name': 'aaaaaaaa',
'resource_type': 'OS::Nova::Server',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': vdu_id,
'id': '1111'
})
res_list.append(resource2)
port_id = uuidsentinel.virtual_link_port_resource_id
vnf_instance.instantiated_vnf_info.vnf_virtual_link_resource_info[
0].vnf_link_ports[0].resource_handle.resource_id = port_id
resource3 = resources.Resource(None, {
'resource_name': 'bbbbbbbb',
'resource_type': 'OS::Neutron::Port',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': port_id,
'id': '1111'
})
res_list.append(resource3)
st_id = uuidsentinel.vdu_resource_id
vnf_instance.instantiated_vnf_info.virtual_storage_resource_info[
0].storage_resource.resource_id = st_id
resource4 = resources.Resource(None, {
'resource_name': 'cccccccc',
'resource_type': 'OS::Cinder::Volume',
'creation_time': '2020-01-01T00:00:01',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': st_id,
'id': '1111'
})
res_list.append(resource4)
mock_list.return_value = res_list
self.openstack.get_grant_resource(
self,
vnf_instance,
vnf_info,
scale_vnf_request,
placement_obj_list,
vim_connection_info,
del_list)
self.assertEqual(3, len(vnf_info['removeResources']))
@mock.patch.object(hc.HeatClient, "update")
def test_scale_out_initial(self, mock_update):
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='SP1',
number_of_steps=1)
vnf_info = {}
vnf_info['attributes'] = {}
vnf_info['attributes']['scale_group'] = '{\"scaleGroupDict\": ' + \
'{ \"SP1\": { \"vdu\": [\"VDU1\"], \"num\": ' + \
'1, \"maxLevel\": 3, \"initialNum\": 0, ' + \
'\"initialLevel\": 0, \"default\": 0 }}}'
vnf_info['attributes']['heat_template'] = \
utils.get_dummy_scale_initial_hot()
vnf_info['attributes']['SP1_res.yaml'] = \
utils.get_dummy_scale_nest_initial_hot()
stack_param_dict = {}
stack_param_dict['nfv'] = {}
stack_param_dict['nfv']['VDU'] = {}
stack_param_dict['nfv']['VDU']['VDU1'] = {}
stack_param_dict['nfv']['VDU']['VDU1']['zone'] = ''
stack_param_dict['nfv']['VDU']['VDU1']['flavor'] = ''
stack_param_dict['nfv']['VDU']['VDU1']['image'] = ''
vnf_info['attributes'].update({'stack_param': str(stack_param_dict)})
vnf_info['instance_id'] = uuidsentinel.stack_id
testjson = '{"id": "c213e465-8220-487e-9464-f79104e81e96", ' + \
'"vnf_instance_id": ' + \
'"47101fb6-bd18-4e04-b2b5-22370a023448", ' + \
'"vnf_lcm_op_occ_id": ' + \
'"f26f181d-7891-4720-b022-b074ec1733ef", ' + \
'"add_resources": [{"resource_definition_id": ' + \
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": ' + \
'"5e4da3c3-4a55-412a-b624-843921f8b51d"}], ' + \
'"vim_assets": {"compute_resource_flavours": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_virtual_compute_desc_id": "VDU1", ' + \
'"vim_flavour_id": "m1.tiny"}], "software_images": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_software_image_id": "VDU1", ' + \
'"vim_software_image_id": "cirros"}]}}'
res_body = jsonutils.loads(testjson)
res_dict = cutils.convert_camelcase_to_snakecase(res_body)
grant_obj = objects.Grant.obj_from_primitive(
res_dict, context=context)
vnf_info['grant'] = grant_obj
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
self.openstack.scale_out_initial(context=self.context,
plugin=self,
auth_attr=None,
vnf_info=vnf_info,
vnf_instance=vnf_instance,
scale_vnf_request=scale_vnf_request,
region_name=None
)
@mock.patch('tacker.vnflcm.utils._get_vnf_package_path')
@mock.patch.object(hc.HeatClient, "update")
def test_scale_out_initial_stack_update(self, mock_update,
mock_get_vnf_package_path):
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='SP1',
number_of_steps=1)
mock_get_vnf_package_path.return_value = self._nfv_sample(
"stack_update_in_heal")
vnf_info = {}
vnf_info['attributes'] = {}
vnf_info['attributes']['scale_group'] = '{\"scaleGroupDict\": ' + \
'{ \"SP1\": { \"vdu\": [\"VDU1\"], \"num\": ' + \
'1, \"maxLevel\": 3, \"initialNum\": 0, ' + \
'\"initialLevel\": 0, \"default\": 0 }}}'
vnf_info['attributes']['heat_template'] = \
utils.get_dummy_scale_initial_hot()
vnf_info['attributes']['SP1_res.yaml'] = \
utils.get_dummy_scale_nest_initial_hot()
stack_param_dict = {}
stack_param_dict['nfv'] = {}
stack_param_dict['nfv']['VDU'] = {}
stack_param_dict['nfv']['VDU']['VDU1'] = {}
stack_param_dict['nfv']['VDU']['VDU1']['zone'] = ''
stack_param_dict['nfv']['VDU']['VDU1']['flavor'] = ''
stack_param_dict['nfv']['VDU']['VDU1']['image'] = ''
stack_param_dict['desired_capacity'] = {'VDU1': 2}
vnf_info['attributes'].update({'stack_param': str(stack_param_dict)})
vnf_info['instance_id'] = uuidsentinel.stack_id
testjson = '{"id": "c213e465-8220-487e-9464-f79104e81e96", ' + \
'"vnf_instance_id": ' + \
'"47101fb6-bd18-4e04-b2b5-22370a023448", ' + \
'"vnf_lcm_op_occ_id": ' + \
'"f26f181d-7891-4720-b022-b074ec1733ef", ' + \
'"add_resources": [{"resource_definition_id": ' + \
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": ' + \
'"5e4da3c3-4a55-412a-b624-843921f8b51d"}], ' + \
'"vim_assets": {"compute_resource_flavours": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_virtual_compute_desc_id": "VDU1", ' + \
'"vim_flavour_id": "m1.tiny"}], "software_images": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_software_image_id": "VDU1", ' + \
'"vim_software_image_id": "cirros"}]}}'
res_body = jsonutils.loads(testjson)
res_dict = cutils.convert_camelcase_to_snakecase(res_body)
grant_obj = objects.Grant.obj_from_primitive(
res_dict, context=context)
vnf_info['grant'] = grant_obj
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
self.openstack.scale_out_initial(context=self.context,
plugin=self,
auth_attr=None,
vnf_info=vnf_info,
vnf_instance=vnf_instance,
scale_vnf_request=scale_vnf_request,
region_name=None
)
@mock.patch.object(hc.HeatClient, "update")
def test_scale_out_initial_zone_none(self, mock_update):
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='SP1',
number_of_steps=1)
vnf_info = {}
add_resources = []
resource = objects.ResourceDefinition(
id='2c6e5cc7-240d-4458-a683-1fe648351280',
type='COMPUTE',
vdu_id='VDU1',
resource_template_id='VDU1')
add_resources.append(resource)
resource = objects.ResourceDefinition(
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
type='LINKPORT',
vdu_id='VDU1',
resource_template_id='PORT1')
add_resources.append(resource)
resource = objects.ResourceDefinition(
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
type='STORAGE',
vdu_id='VDU1',
resource_template_id='ST1')
add_resources.append(resource)
vnf_info['addResources'] = add_resources
vnf_info['attributes'] = {}
vnf_info['attributes']['scale_group'] = '{\"scaleGroupDict\": ' + \
'{ \"SP1\": { \"vdu\": [\"VDU1\"], \"num\": ' + \
'1, \"maxLevel\": 3, \"initialNum\": 0, ' + \
'\"initialLevel\": 0, \"default\": 0 }}}'
vnf_info['attributes']['heat_template'] = \
utils.get_dummy_scale_initial_hot()
vnf_info['attributes']['SP1_res.yaml'] = \
utils.get_dummy_scale_nest_initial_hot()
stack_param_dict = {}
stack_param_dict['nfv'] = {}
stack_param_dict['nfv']['VDU'] = {}
stack_param_dict['nfv']['VDU']['VDU1'] = {}
stack_param_dict['nfv']['VDU']['VDU1']['flavor'] = ''
stack_param_dict['nfv']['VDU']['VDU1']['image'] = ''
vnf_info['attributes'].update({'stack_param': str(stack_param_dict)})
vnf_info['instance_id'] = uuidsentinel.stack_id
testjson = '{"id": "c213e465-8220-487e-9464-f79104e81e96", ' + \
'"vnf_instance_id": ' + \
'"47101fb6-bd18-4e04-b2b5-22370a023448", ' + \
'"vnf_lcm_op_occ_id": ' + \
'"f26f181d-7891-4720-b022-b074ec1733ef", ' + \
'"zones": [{' + \
'"id": ' + \
'"5e4da3c3-4a55-412a-b624-843921f8b51d", ' + \
'"zone_id": ' + \
'"nova", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187"}], ' + \
'"add_resources": [{"resource_definition_id": ' + \
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": ' + \
'"5e4da3c3-4a55-412a-b624-843921f8b51d"}], ' + \
'"vim_assets": {"compute_resource_flavours": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_virtual_compute_desc_id": "VDU1", ' + \
'"vim_flavour_id": "m1.tiny"}], "software_images": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_software_image_id": "VDU1", ' + \
'"vim_software_image_id": "cirros"}]}}'
res_body = jsonutils.loads(testjson)
res_dict = cutils.convert_camelcase_to_snakecase(res_body)
grant_obj = objects.Grant.obj_from_primitive(
res_dict, context=context)
vnf_info['grant'] = grant_obj
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
self.openstack.scale_out_initial(context=self.context,
plugin=self,
auth_attr=None,
vnf_info=vnf_info,
vnf_instance=vnf_instance,
scale_vnf_request=scale_vnf_request,
region_name=None
)
@mock.patch.object(hc.HeatClient, "update")
def test_scale_out_initial_zone_id_none(self, mock_update):
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='SP1',
number_of_steps=1)
vnf_info = {}
add_resources = []
resource = objects.ResourceDefinition(
id='2c6e5cc7-240d-4458-a683-1fe648351280',
type='COMPUTE',
vdu_id='VDU1',
resource_template_id='VDU1')
add_resources.append(resource)
resource = objects.ResourceDefinition(
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
type='LINKPORT',
vdu_id='VDU1',
resource_template_id='PORT1')
add_resources.append(resource)
resource = objects.ResourceDefinition(
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
type='STORAGE',
vdu_id='VDU1',
resource_template_id='ST1')
add_resources.append(resource)
vnf_info['addResources'] = add_resources
vnf_info['attributes'] = {}
vnf_info['attributes']['scale_group'] = '{\"scaleGroupDict\": ' + \
'{ \"SP1\": { \"vdu\": [\"VDU1\"], \"num\": ' + \
'1, \"maxLevel\": 3, \"initialNum\": 0, ' + \
'\"initialLevel\": 0, \"default\": 0 }}}'
vnf_info['attributes']['heat_template'] = \
utils.get_dummy_scale_initial_hot()
vnf_info['attributes']['SP1_res.yaml'] = \
utils.get_dummy_scale_nest_initial_hot()
stack_param_dict = {}
stack_param_dict['nfv'] = {}
stack_param_dict['nfv']['VDU'] = {}
stack_param_dict['nfv']['VDU']['VDU1'] = {}
stack_param_dict['nfv']['VDU']['VDU1']['zone'] = ''
stack_param_dict['nfv']['VDU']['VDU1']['flavor'] = ''
stack_param_dict['nfv']['VDU']['VDU1']['image'] = ''
vnf_info['attributes'].update({'stack_param': str(stack_param_dict)})
vnf_info['instance_id'] = uuidsentinel.stack_id
testjson = '{"id": "c213e465-8220-487e-9464-f79104e81e96", ' + \
'"vnf_instance_id": ' + \
'"47101fb6-bd18-4e04-b2b5-22370a023448", ' + \
'"vnf_lcm_op_occ_id": ' + \
'"f26f181d-7891-4720-b022-b074ec1733ef", ' + \
'"zones": [{' + \
'"id": ' + \
'"5e4da3c3-4a55-412a-b624-843921f8b51d", ' + \
'"zone_id": ' + \
'"", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187"}], ' + \
'"add_resources": [{"resource_definition_id": ' + \
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
'"id": ' + \
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
', {"resource_definition_id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"id": ' + \
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
'"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"zone_id": ' + \
'"5e4da3c3-4a55-412a-b624-843921f8b51d"}], ' + \
'"vim_assets": {"compute_resource_flavours": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_virtual_compute_desc_id": "VDU1", ' + \
'"vim_flavour_id": "m1.tiny"}], "software_images": ' + \
'[{"vim_connection_id": ' + \
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
'"vnfd_software_image_id": "VDU1", ' + \
'"vim_software_image_id": "cirros"}]}}'
res_body = jsonutils.loads(testjson)
res_dict = cutils.convert_camelcase_to_snakecase(res_body)
grant_obj = objects.Grant.obj_from_primitive(
res_dict, context=context)
vnf_info['grant'] = grant_obj
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
self.openstack.scale_out_initial(context=self.context,
plugin=self,
auth_attr=None,
vnf_info=vnf_info,
vnf_instance=vnf_instance,
scale_vnf_request=scale_vnf_request,
region_name=None
)
@mock.patch.object(hc.HeatClient, "resource_get")
@mock.patch.object(hc.HeatClient, "resource_get_list")
def test_get_rollback_ids(self, mock_list, mock_resource):
resource1 = resources.Resource(None, {
'resource_name': 'SP1',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111'
})
mock_resource.return_value = resource1
res_list = []
resource2 = resources.Resource(None, {
'resource_name': 'aaaaaaaa',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce8',
'id': '1111'
})
res_list.append(resource2)
resource3 = resources.Resource(None, {
'resource_name': 'bbbbbbbb',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce9',
'id': '1111'
})
res_list.append(resource3)
resource4 = resources.Resource(None, {
'resource_name': 'cccccccc',
'creation_time': '2020-01-01T00:00:01',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce0',
'id': '1111'
})
res_list.append(resource4)
mock_list.return_value = res_list
vnf_dict = fakes.vnf_dict()
vnf_dict['res_num'] = 2
scale_id_list, scale_name_list, grp_id = \
self.openstack.get_rollback_ids(
None, self.context, vnf_dict, 'SP1', None, None)
self.assertEqual('30435eb8-1472-4cbc-abbe-00b395165ce7', grp_id)
@mock.patch.object(hc.HeatClient, "resource_get")
@mock.patch.object(hc.HeatClient, "resource_get_list")
def test_get_rollback_ids_0(self, mock_list, mock_resource):
resource1 = resources.Resource(None, {
'resource_name': 'SP1',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111'
})
mock_resource.return_value = resource1
res_list = []
resource2 = resources.Resource(None, {
'resource_name': 'aaaaaaaa',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce8',
'id': '1111'
})
res_list.append(resource2)
resource3 = resources.Resource(None, {
'resource_name': 'bbbbbbbb',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce9',
'id': '1111'
})
res_list.append(resource3)
resource4 = resources.Resource(None, {
'resource_name': 'cccccccc',
'creation_time': '2020-01-01T00:00:01',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce0',
'id': '1111'
})
res_list.append(resource4)
mock_list.return_value = res_list
vnf_dict = fakes.vnf_dict()
vnf_dict['res_num'] = 0
scale_id_list, scale_name_list, grp_id = \
self.openstack.get_rollback_ids(
None, self.context, vnf_dict, 'SP1', None, None)
self.assertEqual('30435eb8-1472-4cbc-abbe-00b395165ce7', grp_id)
@mock.patch('tacker.common.clients.OpenstackClients')
@mock.patch('tacker.vnfm.infra_drivers.openstack.update_template.'
'HOTUpdater')
def test_change_ext_conn_vnf_with_userdata(self,
mock_hot_updater,
mock_OpenstackClients_heat):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vnf_dict['vnfd'] = fd_utils.get_vnfd_dict()
vnf_dict['attributes'] = fd_utils.get_vnf_attribute_dict()
vim_connection_info = fd_utils.get_vim_connection_info_object()
change_ext_conn_request = fd_utils.get_change_ext_conn_request()
self.openstack.change_ext_conn_vnf(
self.context, vnf_instance, vnf_dict,
vim_connection_info, change_ext_conn_request)
self.assertEqual(
str(fd_utils.get_expect_stack_param()),
vnf_dict['attributes']['stack_param'])
@mock.patch('tacker.common.clients.OpenstackClients')
@mock.patch('tacker.vnfm.infra_drivers.openstack.update_template'
'.HOTUpdater')
def test_change_ext_conn_vnf_without_userdata(self,
mock_hot_updater,
mock_OpenstackClients_heat):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vnf_dict['vnfd'] = fd_utils.get_vnfd_dict()
vnf_dict['attributes'] = {}
vim_connection_info = fd_utils.get_vim_connection_info_object()
change_ext_conn_request = fd_utils.get_change_ext_conn_request()
hot_instance = mock_hot_updater.return_value
hot_instance.template = fd_utils.get_stack_template()
hot_instance.nested_templates = {
'VDU2.yaml': fd_utils.get_stack_nested_template(),
}
self.openstack.change_ext_conn_vnf(
self.context, vnf_instance, vnf_dict,
vim_connection_info, change_ext_conn_request)
hot_instance.get_templates_from_stack.assert_called_once()
for resource, args in (fd_utils.
get_expected_update_resource_property_calls().items()):
hot_instance.update_resource_property.assert_any_call(
resource, **args)
def test_change_ext_conn_vnf_wait(self):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
# Mock various heat APIs that will be called by heatclient
# during the process of change_ext_conn_vnf_wait.
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS",
"UPDATE_COMPLETE"])
stack = self.openstack.change_ext_conn_vnf_wait(
self.context, vnf_instance, vim_connection_info)
self.assertEqual('UPDATE_COMPLETE', stack.stack_status)
def test_change_ext_conn_vnf_wait_fail(self):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
# Mock various heat APIs that will be called by heatclient
# during the process of change_ext_conn_vnf_wait.
self._response_in_wait_until_stack_ready(["UPDATE_IN_PROGRESS"])
self.openstack.STACK_RETRIES = 1
result = self.assertRaises(vnfm.VNFChangeExtConnWaitFailed,
self.openstack.change_ext_conn_vnf_wait, self.context,
vnf_instance, vim_connection_info)
expected_msg = ("VNF ChangeExtConn action is not completed within 10 "
"seconds ""on stack %s") % inst_vnf_info.instance_id
self.assertIn(expected_msg, str(result))
def test_post_change_ext_conn_vnf(self):
v_s_resource_info = fd_utils.get_virtual_storage_resource_info(
desc_id="storage1", set_resource_id=False)
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(vdu_id="VDU_VNF",
storage_resource_ids=storage_resource_ids, set_resource_id=False)
v_l_resource_info = fd_utils.get_virtual_link_resource_info(
vnfc_resource_info.vnfc_cp_info[0].vnf_link_port_id,
vnfc_resource_info.vnfc_cp_info[0].id)
inst_vnf_info = fd_utils.get_vnf_instantiated_info(
virtual_storage_resource_info=[v_s_resource_info],
vnf_virtual_link_resource_info=[v_l_resource_info],
vnfc_resource_info=[vnfc_resource_info])
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
vim_connection_info = fd_utils.get_vim_connection_info_object()
resources = [{'resource_name': vnfc_resource_info.vdu_id,
'resource_type': vnfc_resource_info.compute_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.vdu_resource_id},
{'resource_name': v_s_resource_info.virtual_storage_desc_id,
'resource_type': v_s_resource_info.storage_resource.
vim_level_resource_type,
'physical_resource_id': uuidsentinel.storage_resource_id},
{'resource_name': vnfc_resource_info.vnfc_cp_info[0].cpd_id,
'resource_type': inst_vnf_info.vnf_virtual_link_resource_info[0].
vnf_link_ports[0].resource_handle.vim_level_resource_type,
'physical_resource_id': uuidsentinel.cp1_resource_id}]
self._responses_in_stack_list(inst_vnf_info.instance_id,
resources=resources)
self.openstack.post_change_ext_conn_vnf(
self.context, vnf_instance, vim_connection_info)
self.assertEqual(vnf_instance.instantiated_vnf_info.
vnfc_resource_info[0].metadata['stack_id'],
inst_vnf_info.instance_id)
# Check if vnfc resource "VDU_VNF" is set with resource_id
self.assertEqual(uuidsentinel.vdu_resource_id,
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].
compute_resource.resource_id)
# Check if virtual storage resource "storage1" is set with resource_id
self.assertEqual(uuidsentinel.storage_resource_id,
vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].storage_resource.resource_id)
# Check if virtual link port "CP1" is set with resource_id
self.assertEqual(uuidsentinel.cp1_resource_id,
vnf_instance.instantiated_vnf_info.
vnf_virtual_link_resource_info[0].vnf_link_ports[0].
resource_handle.resource_id)
@mock.patch.object(hc.HeatClient, 'resource_get')
@mock.patch.object(hc.HeatClient, 'resource_get_list')
def test_scale_resource_update_scale_out_with_grant(
self, mock_list, mock_resource):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='worker_instance',
number_of_steps=1)
vim_connection_info = fd_utils.get_vim_connection_info_object()
vnf_info = {}
v_s_resource_info = (fd_utils.
get_virtual_storage_resource_info_for_grant(desc_id='storage1'))
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info_with_vnf_info(
vdu_id='workerNode', storage_resource_ids=storage_resource_ids)
vnfc_resource_info_list = []
vnfc_resource_info_list.append(vnfc_resource_info)
virtual_st_rsc_list = []
virtual_st_rsc_list.append(v_s_resource_info)
vnf_info['scale_out_vnfc_res_info_list'] = vnfc_resource_info_list
vnf_info['scale_out_virtual_st_rsc_list'] = virtual_st_rsc_list
resource = resources.Resource(None, {
'resource_name': 'worker_instance',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111'
})
resource1 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'attributes': {'key': 'value'}
})
resource_cp = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode',
'attributes': {'fixed_ips': [{'ip_address': '10.10.0.2'}]}
})
resource_st = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode'
})
mock_resource.side_effect = [resource, resource1, resource_cp,
resource_st]
res_list1 = []
res_list2 = []
resource2 = resources.Resource(None, {
'resource_name': 'aaaaaaaa',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '89bd4a61-d33c-cbdd-0329-6429a6083139',
'id': '1111'
})
res_list1.append(resource2)
resource3 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Nova::Server',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource3)
resource4 = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Neutron::Port',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource4)
resource5 = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Cinder::Volume',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource5)
mock_list.side_effect = [res_list1, res_list2]
self.openstack.scale_resource_update(
context, vnf_instance,
scale_vnf_request, vnf_info,
vim_connection_info)
self.assertEqual(
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].id,
uuidsentinel.vnfc_resource_id)
return_vnfc_res = (
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0])
self.assertEqual(return_vnfc_res.vnfc_cp_info[0].id,
uuidsentinel.vnfc_cp_info_id)
self.assertEqual(uuidsentinel.storage_id_1,
vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].id)
self.assertEqual(
len(vnf_instance.instantiated_vnf_info.vnfc_info), 1)
self.assertEqual(
return_vnfc_res.compute_resource.vim_level_resource_type,
'OS::Nova::Server')
self.assertEqual(
(vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].storage_resource.
vim_level_resource_type), 'OS::Cinder::Volume')
@mock.patch.object(hc.HeatClient, 'resource_get')
@mock.patch.object(hc.HeatClient, 'resource_get_list')
def test_scale_resource_update_scale_out(self, mock_list, mock_resource):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
aspect_id='worker_instance',
number_of_steps=1)
vim_connection_info = fd_utils.get_vim_connection_info_object()
v_s_resource_info = (fd_utils.
get_virtual_storage_resource_info(desc_id='storage1'))
storage_resource_ids = [v_s_resource_info.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info_with_vnf_info(
vdu_id='workerNode', storage_resource_ids=storage_resource_ids)
vnfc_resource_info_list = []
vnfc_resource_info_list.append(vnfc_resource_info)
virtual_st_rsc_list = []
virtual_st_rsc_list.append(v_s_resource_info)
vnf_info = {'grant': 'test'}
resource = resources.Resource(None, {
'resource_name': 'worker_instance',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111'
})
resource1 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'attributes': {'key': 'value'}
})
resource_cp = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode',
'attributes': {'fixed_ips': [{'ip_address': '10.10.0.2'}]}
})
resource_st = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '30435eb8-1472-4cbc-abbe-00b395165ce7',
'id': '1111',
'required_by': 'workerNode'
})
mock_resource.side_effect = [resource, resource1, resource_cp,
resource_st]
res_list1 = []
res_list2 = []
resource2 = resources.Resource(None, {
'resource_name': 'aaaaaaaa',
'creation_time': '2020-01-01T00:00:00',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '89bd4a61-d33c-cbdd-0329-6429a6083139',
'id': '1111'
})
res_list1.append(resource2)
resource3 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Nova::Server',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource3)
resource4 = resources.Resource(None, {
'resource_name': 'workerNode_CP2',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Neutron::Port',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource4)
resource5 = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Cinder::Volume',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id': '5a169308-7865-9296-5a4b-a39c743dbe6e',
'id': '1111'
})
res_list2.append(resource5)
mock_list.side_effect = [res_list1, res_list2]
self.openstack.scale_resource_update(
context, vnf_instance,
scale_vnf_request, vnf_info,
vim_connection_info)
self.assertNotEqual(
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].id,
uuidsentinel.vnfc_resource_id)
return_vnfc_res = (
vnf_instance.instantiated_vnf_info.vnfc_resource_info[0])
self.assertNotEqual(return_vnfc_res.vnfc_cp_info[0].id,
uuidsentinel.vnfc_cp_info_id)
self.assertNotEqual(uuidsentinel.storage_id,
vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].id)
self.assertEqual(uuidsentinel.storage_id, v_s_resource_info.id)
self.assertEqual(
len(vnf_instance.instantiated_vnf_info.vnfc_info), 1)
self.assertEqual(
return_vnfc_res.compute_resource.vim_level_resource_type,
'OS::Nova::Server')
self.assertEqual(
(vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].storage_resource.
vim_level_resource_type), 'OS::Cinder::Volume')
@mock.patch.object(hc.HeatClient, 'resource_get_list')
def test_scale_resource_update_scale_in(self, mock_list):
inst_vnf_info = fd_utils.get_vnf_instantiated_info()
vnf_instance = fd_utils.get_vnf_instance_object(
instantiated_vnf_info=inst_vnf_info)
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_IN',
aspect_id='worker_instance',
number_of_steps=1)
vim_connection_info = fd_utils.get_vim_connection_info_object()
vnf_info = {'grant': 'test'}
# instantiated_vnf_info - virtual_storage_resource_info
v_s_resource_info = (fd_utils.
get_virtual_storage_resource_info(desc_id='storage1'))
v_s_resource_info2 = copy.deepcopy(v_s_resource_info)
v_s_resource_info2.id = uuidsentinel.storage_id2
v_s_resource_info2.storage_resource.resource_id = (
uuidsentinel.storage_id2)
vnf_instance.instantiated_vnf_info.virtual_storage_resource_info = [
v_s_resource_info, v_s_resource_info2]
# instantiated_vnf_info - vnfc_resource_info
storage_resource_ids = [v_s_resource_info.id]
storage_resource_ids2 = [v_s_resource_info2.id]
vnfc_resource_info = fd_utils.get_vnfc_resource_info(
vdu_id='workerNode', storage_resource_ids=storage_resource_ids)
vnfc_resource_info2 = fd_utils.get_vnfc_resource_info(
vdu_id='workerNode', storage_resource_ids=storage_resource_ids2)
vnfc_resource_info2.id = uuidsentinel.vnfc_resource_id2
vnfc_resource_info2.compute_resource.resource_id = (
uuidsentinel.storage_resource_id2)
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [
vnfc_resource_info, vnfc_resource_info2]
# instantiated_vnf_info - vnfc_info
vnfc_info = objects.VnfcInfo(id=uuidsentinel.vnfc_info_id,
vdu_id='workerNode', vnfc_state=fields.VnfcState.STARTED)
vnfc_info2 = copy.deepcopy(vnfc_info)
vnfc_info2.id = uuidsentinel.vnfc_info_id2
vnf_instance.instantiated_vnf_info.vnfc_info = [
vnfc_info, vnfc_info2]
# heat resource
res_list1 = []
resource1 = resources.Resource(None, {
'resource_name': 'workerNode',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Nova::Server',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id':
vnfc_resource_info2.compute_resource.resource_id,
'id': '1111'
})
res_list1.append(resource1)
resource2 = resources.Resource(None, {
'resource_name': 'storage1',
'creation_time': '2020-01-01T00:00:00',
'resource_type': 'OS::Cinder::Volume',
'resource_status': 'CREATE_COMPLETE',
'physical_resource_id':
v_s_resource_info2.storage_resource.resource_id,
'id': '1111'
})
res_list1.append(resource2)
mock_list.side_effect = [res_list1]
# execute test target method
self.openstack.scale_resource_update(
context, vnf_instance,
scale_vnf_request, vnf_info,
vim_connection_info)
self.assertEqual(
len(vnf_instance.instantiated_vnf_info.vnfc_resource_info), 1)
self.assertEqual(
(vnf_instance.instantiated_vnf_info.vnfc_resource_info[0].
compute_resource.resource_id),
vnfc_resource_info2.compute_resource.resource_id)
self.assertEqual(
len(vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info), 1)
self.assertEqual(
(vnf_instance.instantiated_vnf_info.
virtual_storage_resource_info[0].storage_resource.resource_id),
v_s_resource_info2.storage_resource.resource_id)
self.assertEqual(
len(vnf_instance.instantiated_vnf_info.vnfc_info), 1)
self.assertEqual(
vnf_instance.instantiated_vnf_info.vnfc_info[0].id,
uuidsentinel.vnfc_info_id2)