Refactor Fake Grant for Simulate NFVO

Currently, the fake_grant.py file used to simulate Response
for GrantRequest cannot return the correct zone-related content
according to the Request and cannot exist as a simulated NFVO
during manual testing.

This refactoring mainly makes the following changes to fake_grant.py.
    1. Append the handling of the contents of the zone so that the
    code can return the corresponding zone result based on the
    placementConstraints in RequestBody.
    2. Modify the original default data of image and flavor, but get
    the result defined in VNFD as the return value.
    3. Add the fake_grant_server.py file, which can be started
    during manual testing and return the Response of GrantRequest
    as simulated NFVO.

Change-Id: I322bbeee81db5db199fb23c7e9115925fd04d344
This commit is contained in:
Yi Feng 2021-12-14 11:21:10 +09:00 committed by Ayumu Ueha
parent f1fbcbb9b9
commit 15358675ed
6 changed files with 436 additions and 88 deletions

View File

@ -400,6 +400,8 @@ topology_template:
leaf: 1048576
targets: [ internalVL3 ]
# For zuul test, because it only have one Availability Zone,
# so it cannot realize the AntiAffinityRule for VDU1.
- policy_antiaffinity_vdu1:
type: tosca.policies.nfv.AntiAffinityRule
targets: [ VDU1 ]

View File

@ -101,6 +101,7 @@ class BaseTackerTest(base.BaseTestCase):
cls.h_client = cls.heatclient()
cls.glance_client = cls.glanceclient()
cls.cinder_client = cls.cinderclient()
cls.nova_client = cls.novaclient()
@classmethod
def get_credentials(cls, vim_conf_file=None):

View File

@ -18,6 +18,7 @@ from urllib.parse import urlparse
import yaml
import zipfile
from novaclient import client as nova_client
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
@ -396,6 +397,15 @@ class BaseVnfLcmTest(base.BaseTackerTest):
return image_id_list
@classmethod
def _list_zone(cls):
try:
zone = cls.nova_client.services.list()
except nova_client.exceptions.ClientException:
print("availability zone does not exists.", flush=True)
return []
return zone
def _register_subscription(self, request_body, http_client=None):
if http_client is None:
http_client = self.http_client

View File

@ -11,7 +11,11 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
import yaml
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
from tacker.tests import uuidsentinel
@ -49,21 +53,63 @@ class Grant:
}]
@staticmethod
def _make_add_resources(req_add_resources):
def _make_add_resources(req_add_resources, zones=None,
placement_constraints=None):
add_resources = []
for req_add_resource in req_add_resources:
res_add_resource = {
"resourceDefinitionId": req_add_resource['id'],
"vimConnectionId": uuidsentinel.vim_connection_id
}
if req_add_resource['type'] == 'COMPUTE':
res_add_resource["zoneId"] = uuidsentinel.zone_id
if placement_constraints:
zone_id_dict = (Grant.
_get_zone_id_from_placement_constraint(
placement_constraints, zones))
if zone_id_dict[req_add_resource['id']]:
res_add_resource["zoneId"] = zone_id_dict[
req_add_resource['id']]
add_resources.append(res_add_resource)
return add_resources
@staticmethod
def _get_zone_id_from_placement_constraint(placement_constraints, zones):
zone_id_dict = {}
for placement_constraint in placement_constraints:
for index in range(len(placement_constraint['resource'])):
if placement_constraint[
'affinityOrAntiAffinity'] == 'AFFINITY':
# In this fake_grant, if the user set 'AFFINITY'
# rule in VNF Package, it will always use the first
# `Availability Zone` to create VM.
zone_id_dict[placement_constraint[
'resource'][index]['resourceId']] = zones[0]['id']
else:
try:
zone_id_dict[placement_constraint[
'resource'][index]['resourceId']] = zones[
index]['id']
except IndexError:
print(
"The number of 'Availability Zone'"
"cannot support current case.")
raise IndexError
return zone_id_dict
@staticmethod
def _make_zones(zone_name_list):
zone = []
for name in zone_name_list:
zone_dict = {
"id": uuidutils.generate_uuid(),
"zoneId": name,
"vimConnectionId": uuidsentinel.vim_connection_id
}
zone.append(zone_dict)
return zone
@staticmethod
def _make_remove_resources(req_remove_resources):
res_remove_resources = []
@ -77,7 +123,8 @@ class Grant:
return res_remove_resources
@staticmethod
def _make_update_resources(req_update_resources):
def _make_update_resources(req_update_resources,
zones=None, placement_constraints=None):
res_update_resources = []
for req_update_resource in req_update_resources:
res_update_resource = {
@ -85,44 +132,61 @@ class Grant:
"vimConnectionId": uuidsentinel.vim_connection_id
}
if req_update_resource['type'] == 'COMPUTE':
res_update_resource["zoneId"] = uuidsentinel.zone_id
if placement_constraints:
zone_id_dict = (Grant.
_get_zone_id_from_placement_constraint(
placement_constraints, zones))
if zone_id_dict[req_update_resource['id']]:
res_update_resource["zoneId"] = zone_id_dict[
req_update_resource['id']]
res_update_resources.append(res_update_resource)
return res_update_resources
@staticmethod
def _make_vim_assets(image_id, flavour_id="1"):
def get_vdu_list(add_resources):
vdu_list = []
for add_resource in add_resources:
if add_resource['type'] == 'COMPUTE':
vdu_list.append(add_resource['vduId'])
return vdu_list
@staticmethod
def _make_vim_assets(add_resources, image_id_dict, flavour_id_dict):
# set m1.tiny="1" for flavour_id
vdu_list = Grant.get_vdu_list(add_resources)
flavors = [Grant._generate_flavour(vdu, flavour_id_dict)
for vdu in vdu_list if flavour_id_dict.get(vdu)]
images = [Grant._generate_image(vdu, image_id_dict)
for vdu in vdu_list if image_id_dict.get(vdu)]
vim_assets = {
"computeResourceFlavours": [
{
"vimConnectionId": uuidsentinel.vim_connection_id,
"vnfdVirtualComputeDescId": "VDU1",
"vimFlavourId": flavour_id
},
{
"vimConnectionId": uuidsentinel.vim_connection_id,
"vnfdVirtualComputeDescId": "VDU2",
"vimFlavourId": flavour_id
}
],
"softwareImages": [
{
"vimConnectionId": uuidsentinel.vim_connection_id,
"vnfdSoftwareImageId": "VDU1",
"vimSoftwareImageId": image_id
},
{
"vimConnectionId": uuidsentinel.vim_connection_id,
"vnfdSoftwareImageId": "VDU2",
"vimSoftwareImageId": image_id
}
]
'computeResourceFlavours': flavors,
'softwareImages': images,
}
return vim_assets
@staticmethod
def _generate_flavour(vdu, flavour_id_dict):
if flavour_id_dict.get(vdu):
return {
"vimConnectionId": uuidsentinel.vim_connection_id,
"vnfdVirtualComputeDescId": vdu,
"vimFlavourId": flavour_id_dict[vdu]
}
return None
@staticmethod
def _generate_image(vdu, image_id_dict):
if image_id_dict.get(vdu):
return {
"vimConnectionId": uuidsentinel.vim_connection_id,
"vnfdSoftwareImageId": vdu,
"vimSoftwareImageId": image_id_dict[vdu]
}
return None
@staticmethod
def _make_response_template(request_body):
res = {
@ -148,64 +212,72 @@ class Grant:
return res
@staticmethod
def _convert_body_to_dict(body):
def convert_body_to_dict(body):
if isinstance(body, str):
return jsonutils.loads(body)
return body
@staticmethod
def make_inst_response_body(request_body, tenant_id, image_id):
request_body = Grant._convert_body_to_dict(request_body)
def make_inst_response_body(
request_body, tenant_id, image_id_dict,
flavour_id_dict, zone_name_list):
request_body = Grant.convert_body_to_dict(request_body)
res = Grant._make_response_template(request_body)
res["vimConnections"] = Grant._make_vim_connection_info(tenant_id)
res["zones"] = Grant.ZONES
res["zones"] = Grant._make_zones(zone_name_list)
if 'addResources' in request_body.keys():
res["addResources"] = Grant._make_add_resources(
request_body['addResources'])
res["vimAssets"] = Grant._make_vim_assets(
image_id)
request_body['addResources'], res["zones"],
request_body.get('placementConstraints'))
res["vimAssets"] = Grant._make_vim_assets(
request_body['addResources'],
image_id_dict,
flavour_id_dict)
res["additionalParams"] = Grant.ADDITIONAL_PARAMS
return res
@staticmethod
def make_heal_response_body(request_body, tenant_id, image_id):
request_body = Grant._convert_body_to_dict(request_body)
def make_heal_response_body(request_body, tenant_id, image_id_dict,
flavour_id_dict, zone_name_list):
request_body = Grant.convert_body_to_dict(request_body)
res = Grant._make_response_template(request_body)
res["vimConnections"] = Grant._make_vim_connection_info(tenant_id)
res["zones"] = Grant.ZONES
res["zones"] = Grant._make_zones(zone_name_list)
if 'addResources' in request_body.keys():
res["addResources"] = Grant._make_add_resources(
request_body['addResources'])
request_body['addResources'], res["zones"],
request_body.get('placementConstraints'))
res["vimAssets"] = Grant._make_vim_assets(
request_body['addResources'],
image_id_dict,
flavour_id_dict)
if 'removeResources' in request_body.keys():
res["removeResources"] = Grant._make_remove_resources(
request_body['removeResources'])
if 'updateResources' in request_body.keys():
res["updateResources"] = Grant._make_update_resources(
request_body['updateResources'])
res["vimAssets"] = Grant._make_vim_assets(image_id)
request_body['updateResources'], res["zones"],
request_body.get('placementConstraints'))
return res
@staticmethod
def make_scaleout_response_body(request_body, tenant_id, image_id):
request_body = Grant._convert_body_to_dict(request_body)
def make_scale_response_body(
request_body, tenant_id, image_id_dict, flavour_id_dict,
zone_name_list):
request_body = Grant.convert_body_to_dict(request_body)
res = Grant._make_response_template(request_body)
res["vimConnections"] = Grant._make_vim_connection_info(tenant_id)
res["zones"] = Grant.ZONES
if 'addResources' in request_body.keys():
res["zones"] = Grant._make_zones(zone_name_list)
res["addResources"] = Grant._make_add_resources(
request_body['addResources'])
res["vimAssets"] = Grant._make_vim_assets(
image_id)
return res
@staticmethod
def make_scalein_response_body(request_body):
request_body = Grant._convert_body_to_dict(request_body)
res = Grant._make_response_template(request_body)
request_body['addResources'], res["zones"],
request_body.get('placementConstraints'))
res["vimAssets"] = Grant._make_vim_assets(
request_body['addResources'],
image_id_dict,
flavour_id_dict)
res["vimConnections"] = Grant._make_vim_connection_info(tenant_id)
if 'removeResources' in request_body.keys():
res["removeResources"] = Grant._make_remove_resources(
request_body['removeResources'])
@ -214,7 +286,7 @@ class Grant:
@staticmethod
def make_term_response_body(request_body):
request_body = Grant._convert_body_to_dict(request_body)
request_body = Grant.convert_body_to_dict(request_body)
res = Grant._make_response_template(request_body)
if 'removeResources' in request_body.keys():
res["removeResources"] = Grant._make_remove_resources(
@ -223,15 +295,76 @@ class Grant:
return res
@staticmethod
def make_change_ext_conn_response_body(request_body, tenant_id, image_id):
request_body = Grant._convert_body_to_dict(request_body)
def make_change_ext_conn_response_body(
request_body, tenant_id, zone_name_list):
request_body = Grant.convert_body_to_dict(request_body)
res = Grant._make_response_template(request_body)
res["vimConnections"] = Grant._make_vim_connection_info(tenant_id)
res["zones"] = Grant.ZONES
res["zones"] = Grant._make_zones(zone_name_list)
if 'updateResources' in request_body.keys():
res["updateResources"] = Grant._make_update_resources(
request_body['updateResources'])
res["vimAssets"] = Grant._make_vim_assets(image_id)
request_body['updateResources'], res["zones"],
request_body.get('placementConstraints'))
res["additionalParams"] = Grant.ADDITIONAL_PARAMS
return res
@staticmethod
def get_sw_image(package_dir="functional6"):
sample_name = package_dir
csar_package_path = os.path.abspath(
os.path.join(
os.path.dirname(__file__),
"../../../etc/samples/etsi/nfv",
sample_name))
yaml_file = os.path.join(csar_package_path,
"Definitions/helloworld3_df_simple.yaml")
with open(yaml_file, 'r', encoding='utf-8') as f:
config_content = yaml.safe_load(f.read())
nodes = (config_content
.get('topology_template', {})
.get('node_templates', {}))
types = ['tosca.nodes.nfv.Vdu.Compute',
'tosca.nodes.nfv.Vdu.VirtualBlockStorage']
sw_image = {}
for name, data in nodes.items():
if (data['type'] in types and
data.get('properties', {}).get('sw_image_data')):
image = data['properties']['sw_image_data']['name']
sw_image[name] = image
return sw_image
@staticmethod
def get_compute_flavor(package_dir="functional6"):
sample_name = package_dir
csar_package_path = os.path.abspath(
os.path.join(
os.path.dirname(__file__),
"../../../etc/samples/etsi/nfv",
sample_name))
yaml_file = os.path.join(csar_package_path,
"Definitions/helloworld3_df_simple.yaml")
with open(yaml_file, 'r', encoding='utf-8') as f:
config_content = yaml.safe_load(f.read())
nodes = (config_content
.get('topology_template', {})
.get('node_templates', {}))
types = ['tosca.nodes.nfv.Vdu.Compute',
'tosca.nodes.nfv.Vdu.VirtualBlockStorage']
flavor = {}
for name, data in nodes.items():
if (data['type'] in types and
data.get('capabilities', {})
.get('virtual_compute', {})
.get('properties', {})
.get('requested_additional_capabilities', {})
.get('properties')):
flavour = data['capabilities']['virtual_compute'][
'properties']['requested_additional_capabilities'][
'properties']['requested_additional_capability_name']
flavor[name] = flavour
return flavor

View File

@ -0,0 +1,159 @@
#
# 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 re
from flask import Flask
from flask import request
from keystoneauth1.identity import v3
from keystoneauth1 import session
from novaclient import client as nova_client
from tackerclient.v1_0 import client as tacker_client
import yaml
from tacker.tests import constants
from tacker.tests.functional.sol_separated_nfvo.vnflcm.fake_grant import Grant
from tacker.tests.utils import read_file
class GrantServer:
app = Flask(__name__)
def __init__(self):
self.client = self.tackerclient()
self.nova_client = self.novaclient()
@staticmethod
def log_http_request():
message = "Method:{0}, Url:{1}, Headers:{2}, Body:{3}"
body = ""
ct = "{0}".format(request.headers.get("Content-type"))
print(ct)
if len(request.get_data()) > 0 and not re.match(
".*?application/zip.*?", ct):
body = request.get_data().decode("utf-8")
hs = ""
ff = "{0}:{1};"
for k, v in request.headers.items():
hs += ff.format(k, v)
message = message.format(request.method, request.url, hs, body)
print(message)
@staticmethod
def log_http_response(resp):
message = "Status:{0}, Body:{1}"
body = ""
if len(resp.get_data()) > 0:
try:
body = resp.get_data().decode("utf-8")
except AttributeError:
body = "binary file."
message = message.format(resp.status_code, body)
print(message)
return resp
def get_auth_session(self):
vim_params = self.get_credentials()
auth = v3.Password(
auth_url=vim_params['auth_url'],
username=vim_params['username'],
password=vim_params['password'],
project_name=vim_params['project_name'],
user_domain_name=vim_params['user_domain_name'],
project_domain_name=vim_params['project_domain_name'])
verify = 'True' == vim_params.pop('cert_verify', 'False')
auth_ses = session.Session(auth=auth, verify=verify)
return auth_ses
def get_credentials(self):
vim_params = yaml.safe_load(read_file('local-vim.yaml'))
vim_params['auth_url'] += '/v3'
return vim_params
def tackerclient(self):
auth_session = self.get_auth_session()
return tacker_client.Client(session=auth_session, retries=5)
def novaclient(self):
vim_params = self.get_credentials()
auth = v3.Password(auth_url=vim_params['auth_url'],
username=vim_params['username'],
password=vim_params['password'],
project_name=vim_params['project_name'],
user_domain_name=vim_params['user_domain_name'],
project_domain_name=vim_params['project_domain_name'])
verify = 'True' == vim_params.pop('cert_verify', 'False')
auth_ses = session.Session(auth=auth, verify=verify)
return nova_client.Client(constants.NOVA_CLIENT_VERSION,
session=auth_ses)
def list_zone(self):
try:
zone = self.nova_client.services.list()
except nova_client.exceptions.ClientException:
print("availability zone does not exists.", flush=True)
return []
return zone
def get_vim(self):
vim_list = self.client.list_vims()
vim = self.get_vim_specified(vim_list, 'openstack-admin-vim')
if not vim:
assert False, "vim_list is Empty: Default VIM is missing"
return vim
def get_vim_specified(self, vim_list, vim_name):
if len(vim_list.values()) == 0:
assert False, "vim_list is Empty: Default VIM is missing"
for vim_list in vim_list.values():
for vim in vim_list:
if vim['name'] == vim_name:
return vim
return None
@GrantServer.app.route('/grant/v1/grants', methods=['POST'])
def grant():
body = request.json
request_body = Grant.convert_body_to_dict(body)
glance_image = Grant.get_sw_image("functional5")
flavour_vdu_dict = Grant.get_compute_flavor("functional5")
availability_zone_info = GrantServer().list_zone()
zone_name_list = list(set(
[zone.zone for zone in availability_zone_info
if zone.binary == 'nova-compute']))
vim = GrantServer().get_vim()
if request_body['operation'] == 'INSTANTIATE':
return Grant.make_inst_response_body(
body, vim['tenant_id'], glance_image, flavour_vdu_dict,
zone_name_list)
if request_body['operation'] == 'SCALE':
return Grant.make_scale_response_body(
body, vim['tenant_id'], glance_image, flavour_vdu_dict,
zone_name_list)
if request_body['operation'] == 'HEAL':
return Grant.make_heal_response_body(
body, vim['tenant_id'], glance_image, flavour_vdu_dict,
zone_name_list)
if request_body['operation'] == 'CHANGE_EXT_CONN':
return Grant.make_change_ext_conn_response_body(
body, vim['tenant_id'], zone_name_list)
if request_body['operation'] == 'TERMINATE':
return Grant.make_term_response_body(body)
# Start Fake_Grant_Server for manual test
GrantServer.app.before_request(GrantServer.log_http_request)
GrantServer.app.after_request(GrantServer.log_http_response)
GrantServer.app.run(host="127.0.0.1", port=9990, debug=False)

View File

@ -110,8 +110,13 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
- Show subscription.
"""
vnf_package_info = self._register_vnf_package_mock_response()
glance_image = self._list_glance_image()[0]
glance_image = fake_grant.Grant.get_sw_image()
flavour_vdu_dict = fake_grant.Grant.get_compute_flavor()
zone_name_list = []
availability_zone_info = self._list_zone()
zone_name_list = list(set(
[zone.zone for zone in availability_zone_info
if zone.binary == 'nova-compute']))
# Create subscription and register it.
callback_url = os.path.join(vnflcm_base.MOCK_NOTIFY_CALLBACK_URL,
self._testMethodName)
@ -142,8 +147,11 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_inst_response_body(req_body,
self.vim['tenant_id'], glance_image.id))
req_body: fake_grant.Grant.make_inst_response_body(
req_body,
self.vim['tenant_id'], glance_image,
flavour_vdu_dict,
zone_name_list))
# Instantiate vnf instance
request_body = fake_vnflcm.VnfInstances.\
@ -175,7 +183,7 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
req_body: fake_grant.Grant.make_change_ext_conn_response_body(
req_body,
self.vim['tenant_id'],
glance_image.id))
zone_name_list))
# Change external connectivity
request_body = \
@ -255,7 +263,13 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
- Delete subscription
"""
vnf_package_info = self._register_vnf_package_mock_response()
glance_image = self._list_glance_image()[0]
glance_image = fake_grant.Grant.get_sw_image()
flavour_vdu_dict = fake_grant.Grant.get_compute_flavor()
zone_name_list = []
availability_zone_info = self._list_zone()
zone_name_list = list(set(
[zone.zone for zone in availability_zone_info
if zone.binary == 'nova-compute']))
# Create subscription and register it.
callback_url = os.path.join(vnflcm_base.MOCK_NOTIFY_CALLBACK_URL,
@ -284,8 +298,12 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_inst_response_body(req_body,
self.vim['tenant_id'], glance_image.id))
req_body: fake_grant.Grant.make_inst_response_body(
req_body,
self.vim['tenant_id'],
glance_image,
flavour_vdu_dict,
zone_name_list))
# Instantiate vnf instance
request_body = fake_vnflcm.VnfInstances.\
@ -305,8 +323,12 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_heal_response_body(req_body,
self.vim['tenant_id'], glance_image.id))
req_body: fake_grant.Grant.make_heal_response_body(
req_body,
self.vim['tenant_id'],
glance_image,
flavour_vdu_dict,
zone_name_list))
# Heal vnf (exists vnfc_instace_id)
vnfc_instance_id_list = []
@ -369,7 +391,15 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
"""
vnf_package_info = self._register_vnf_package_mock_response(
package_dir='functional7')
glance_image = self._list_glance_image()[0]
glance_image = fake_grant.Grant.get_sw_image(
package_dir='functional7')
flavour_vdu_dict = fake_grant.Grant.get_compute_flavor(
package_dir='functional7')
zone_name_list = []
availability_zone_info = self._list_zone()
zone_name_list = list(set(
[zone.zone for zone in availability_zone_info
if zone.binary == 'nova-compute']))
# Create subscription and register it.
callback_url = os.path.join(vnflcm_base.MOCK_NOTIFY_CALLBACK_URL,
@ -398,8 +428,12 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_inst_response_body(req_body,
self.vim['tenant_id'], glance_image.id))
req_body: fake_grant.Grant.make_inst_response_body(
req_body,
self.vim['tenant_id'],
glance_image,
flavour_vdu_dict,
zone_name_list))
# Instantiate vnf instance
request_body = fake_vnflcm.VnfInstances.\
@ -416,11 +450,16 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
self.assertEqual(200, resp.status_code)
# Set Fake server response for Grant-Req(Scale-out)
vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_scaleout_response_body(req_body,
self.vim['tenant_id'], glance_image.id))
vnflcm_base.FAKE_SERVER_MANAGER.set_callback(
'POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_scale_response_body(
req_body,
self.vim['tenant_id'],
glance_image,
flavour_vdu_dict,
zone_name_list))
# Scale-out vnf instance
stack = self._get_heat_stack(vnf_instance_id)
@ -437,10 +476,14 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
scale_type='SCALE_OUT')
# Set Fake server response for Grant-Req(Scale-in)
vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_scalein_response_body(req_body))
vnflcm_base.FAKE_SERVER_MANAGER.set_callback(
'POST',
fake_grant.Grant.GRANT_REQ_PATH, status_code=201,
callback=lambda req_headers,
req_body: fake_grant.Grant.make_scale_response_body(
req_body,
self.vim['tenant_id'], glance_image, flavour_vdu_dict,
zone_name_list))
# Scale-in vnf instance
stack = self._get_heat_stack(vnf_instance_id)