975 lines
43 KiB
Python
975 lines
43 KiB
Python
# Copyright (C) 2020 NTT DATA
|
|
# 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 ddt
|
|
import mock
|
|
from oslo_serialization import jsonutils
|
|
from six.moves import http_client
|
|
from webob import exc
|
|
|
|
from tacker.api.vnflcm.v1 import controller
|
|
from tacker.common import exceptions
|
|
from tacker.conductor.conductorrpc.vnf_lcm_rpc import VNFLcmRPCAPI
|
|
from tacker.extensions import nfvo
|
|
from tacker import objects
|
|
from tacker.objects import fields
|
|
from tacker.tests import constants
|
|
from tacker.tests.unit import base
|
|
from tacker.tests.unit import fake_request
|
|
from tacker.tests.unit.vnflcm import fakes
|
|
from tacker.tests import uuidsentinel
|
|
from tacker.vnfm import vim_client
|
|
|
|
|
|
@ddt.ddt
|
|
class TestController(base.TestCase):
|
|
|
|
def setUp(self):
|
|
super(TestController, self).setUp()
|
|
self.controller = controller.VnfLcmController()
|
|
|
|
@property
|
|
def app(self):
|
|
return fakes.wsgi_app_v1()
|
|
|
|
@mock.patch.object(objects.vnf_instance, '_vnf_instance_create')
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
def test_create_without_name_and_description(
|
|
self, mock_get_by_id, mock_vnf_instance_create):
|
|
mock_get_by_id.return_value = fakes.return_vnf_package_vnfd()
|
|
|
|
updates = {'vnf_instance_description': None,
|
|
'vnf_instance_name': None}
|
|
mock_vnf_instance_create.return_value =\
|
|
fakes.return_vnf_instance_model(**updates)
|
|
|
|
req = fake_request.HTTPRequest.blank('/vnf_instances')
|
|
body = {'vnfdId': uuidsentinel.vnfd_id}
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call create API
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.CREATED, resp.status_code)
|
|
|
|
updates = {'vnfInstanceDescription': None, 'vnfInstanceName': None}
|
|
expected_vnf = fakes.fake_vnf_instance_response(**updates)
|
|
location_header = ('http://localhost/vnflcm/v1/vnf_instances/%s'
|
|
% resp.json['id'])
|
|
|
|
self.assertEqual(expected_vnf, resp.json)
|
|
self.assertEqual(location_header, resp.headers['location'])
|
|
|
|
@mock.patch.object(objects.vnf_instance, '_vnf_instance_create')
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
def test_create_with_name_and_description(
|
|
self, mock_get_by_id, mock_vnf_instance_create):
|
|
mock_get_by_id.return_value = fakes.return_vnf_package_vnfd()
|
|
updates = {'vnf_instance_description': 'SampleVnf Description',
|
|
'vnf_instance_name': 'SampleVnf'}
|
|
mock_vnf_instance_create.return_value =\
|
|
fakes.return_vnf_instance_model(**updates)
|
|
|
|
body = {'vnfdId': uuidsentinel.vnfd_id,
|
|
"vnfInstanceName": "SampleVnf",
|
|
"vnfInstanceDescription": "SampleVnf Description"}
|
|
req = fake_request.HTTPRequest.blank('/vnf_instances')
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Create API
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.CREATED, resp.status_code)
|
|
updates = {"vnfInstanceName": "SampleVnf",
|
|
"vnfInstanceDescription": "SampleVnf Description"}
|
|
expected_vnf = fakes.fake_vnf_instance_response(**updates)
|
|
location_header = ('http://localhost/vnflcm/v1/vnf_instances/%s'
|
|
% resp.json['id'])
|
|
|
|
self.assertEqual(expected_vnf, resp.json)
|
|
self.assertEqual(location_header, resp.headers['location'])
|
|
|
|
@ddt.data(
|
|
{'attribute': 'vnfdId', 'value': True,
|
|
'expected_type': 'uuid'},
|
|
{'attribute': 'vnfdId', 'value': 123,
|
|
'expected_type': 'uuid'},
|
|
{'attribute': 'vnfInstanceName', 'value': True,
|
|
'expected_type': "name_allow_zero_min_length"},
|
|
{'attribute': 'vnfInstanceName', 'value': 123,
|
|
'expected_type': "name_allow_zero_min_length"},
|
|
{'attribute': 'vnfInstanceDescription', 'value': True,
|
|
'expected_type': 'description'},
|
|
{'attribute': 'vnfInstanceDescription', 'value': 123,
|
|
'expected_type': 'description'},
|
|
)
|
|
@ddt.unpack
|
|
def test_create_with_invalid_request_body(
|
|
self, attribute, value, expected_type):
|
|
"""value of attribute in body is of invalid type"""
|
|
body = {"vnfInstanceName": "SampleVnf",
|
|
"vnfdId": "29c770a3-02bc-4dfc-b4be-eb173ac00567",
|
|
"vnfInstanceDescription": "VNF Description"}
|
|
req = fake_request.HTTPRequest.blank('/vnf_instances')
|
|
body.update({attribute: value})
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
exception = self.assertRaises(
|
|
exceptions.ValidationError, self.controller.create,
|
|
req, body=body)
|
|
if expected_type == 'uuid':
|
|
expected_message = ("Invalid input for field/attribute "
|
|
"{attribute}. Value: {value}. {value} is not "
|
|
"of type 'string'".
|
|
format(value=value, attribute=attribute,
|
|
expected_type=expected_type))
|
|
elif expected_type in ["name_allow_zero_min_length", "description"]:
|
|
expected_message = ("Invalid input for field/attribute "
|
|
"{attribute}. " "Value: {value}. {value} is "
|
|
"not of type 'string'".
|
|
format(value=value, attribute=attribute,
|
|
expected_type=expected_type))
|
|
|
|
self.assertEqual(expected_message, exception.msg)
|
|
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
def test_create_non_existing_vnf_package_vnfd(self, mock_vnf_by_id):
|
|
mock_vnf_by_id.side_effect = exceptions.VnfPackageVnfdNotFound
|
|
body = {'vnfdId': uuidsentinel.vnfd_id}
|
|
req = fake_request.HTTPRequest.blank('/vnf_instances')
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
self.assertRaises(exc.HTTPBadRequest, self.controller.create, req,
|
|
body=body)
|
|
|
|
def test_create_without_vnfd_id(self):
|
|
body = {"vnfInstanceName": "SampleVnfInstance"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances')
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
|
|
@ddt.data('PATCH', 'PUT', 'HEAD', 'DELETE')
|
|
def test_create_not_allowed_http_method(self, method):
|
|
"""Wrong HTTP method"""
|
|
body = {"vnfdId": uuidsentinel.vnfd_id}
|
|
req = fake_request.HTTPRequest.blank('/vnf_instances')
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = method
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
|
|
|
@ddt.data({'name': "A" * 256, 'description': "VNF Description"},
|
|
{'name': 'Fake-VNF', 'description': "A" * 1025})
|
|
@ddt.unpack
|
|
def test_create_max_length_exceeded_for_vnf_name_and_description(
|
|
self, name, description):
|
|
# vnf instance_name and description with length greater than max
|
|
# length defined
|
|
body = {"vnfInstanceName": name,
|
|
"vnfdId": uuidsentinel.vnfd_id,
|
|
"vnfInstanceDescription": description}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances')
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
|
|
@mock.patch.object(vim_client.VimClient, "get_vim")
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfInstance, "save")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
@mock.patch.object(VNFLcmRPCAPI, "instantiate")
|
|
def test_instantiate_with_deployment_flavour(
|
|
self, mock_instantiate, mock_vnf_package_get_by_id,
|
|
mock_vnf_package_vnfd_get_by_id, mock_save,
|
|
mock_vnf_instance_get_by_id, mock_get_vim):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
|
|
body = {"flavourId": "simple"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
|
mock_instantiate.assert_called_once()
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
def test_instantiate_with_non_existing_deployment_flavour(
|
|
self, mock_vnf_package_get_by_id, mock_vnf_package_vnfd_get_by_id,
|
|
mock_vnf_instance_get_by_id):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
|
|
body = {"flavourId": "invalid"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("No flavour with id 'invalid'.",
|
|
resp.json['badRequest']['message'])
|
|
|
|
@mock.patch.object(vim_client.VimClient, "get_vim")
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfInstance, "save")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
@mock.patch.object(VNFLcmRPCAPI, "instantiate")
|
|
def test_instantiate_with_instantiation_level(
|
|
self, mock_instantiate, mock_vnf_package_get_by_id,
|
|
mock_vnf_package_vnfd_get_by_id, mock_save,
|
|
mock_vnf_instance_get_by_id, mock_get_vim):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
|
|
body = {"flavourId": "simple",
|
|
"instantiationLevelId": "instantiation_level_1"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
|
mock_instantiate.assert_called_once()
|
|
|
|
@mock.patch.object(vim_client.VimClient, "get_vim")
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfInstance, "save")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
@mock.patch.object(VNFLcmRPCAPI, "instantiate")
|
|
def test_instantiate_with_no_inst_level_in_flavour(
|
|
self, mock_instantiate, mock_vnf_package_get_by_id,
|
|
mock_vnf_package_vnfd_get_by_id, mock_save,
|
|
mock_vnf_instance_get_by_id, mock_get_vim):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
vnf_package = fakes.return_vnf_package_with_deployment_flavour()
|
|
vnf_package.vnf_deployment_flavours[0].instantiation_levels = None
|
|
mock_vnf_package_get_by_id.return_value = vnf_package
|
|
|
|
# No instantiation level in deployment flavour but it's passed in the
|
|
# request
|
|
body = {"flavourId": "simple",
|
|
"instantiationLevelId": "instantiation_level_1"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("No instantiation level with id "
|
|
"'instantiation_level_1'.", resp.json['badRequest']['message'])
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
@mock.patch.object(VNFLcmRPCAPI, "instantiate")
|
|
def test_instantiate_with_non_existing_instantiation_level(
|
|
self, mock_instantiate, mock_vnf_package_get_by_id,
|
|
mock_vnf_package_vnfd_get_by_id,
|
|
mock_vnf_instance_get_by_id):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
|
|
body = {"flavourId": "simple",
|
|
"instantiationLevelId": "non-existing"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("No instantiation level with id 'non-existing'.",
|
|
resp.json['badRequest']['message'])
|
|
|
|
@mock.patch.object(vim_client.VimClient, "get_vim")
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfInstance, "save")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
@mock.patch.object(VNFLcmRPCAPI, "instantiate")
|
|
def test_instantiate_with_vim_connection(
|
|
self, mock_instantiate, mock_vnf_package_get_by_id,
|
|
mock_vnf_package_vnfd_get_by_id, mock_save,
|
|
mock_vnf_instance_get_by_id, mock_get_vim):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
|
|
body = {"flavourId": "simple",
|
|
"vimConnectionInfo": [
|
|
{"id": uuidsentinel.vim_connection_id,
|
|
"vimId": uuidsentinel.vim_id,
|
|
"vimType": 'openstack'}
|
|
]}
|
|
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
|
mock_instantiate.assert_called_once()
|
|
|
|
@mock.patch.object(vim_client.VimClient, "get_vim")
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
def test_instantiate_with_non_existing_vim(
|
|
self, mock_vnf_package_get_by_id, mock_vnf_package_vnfd_get_by_id,
|
|
mock_vnf_instance_get_by_id, mock_get_vim):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
mock_get_vim.side_effect = nfvo.VimNotFoundException
|
|
|
|
body = {"flavourId": "simple",
|
|
"vimConnectionInfo": [
|
|
{"id": uuidsentinel.vim_connection_id,
|
|
"vimId": uuidsentinel.vim_id,
|
|
"vimType": 'openstack'}
|
|
]}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("VimConnection id is not found: %s" %
|
|
uuidsentinel.vim_id, resp.json['badRequest']['message'])
|
|
|
|
@mock.patch.object(vim_client.VimClient, "get_vim")
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
def test_instantiate_with_non_existing_region_vim(
|
|
self, mock_vnf_package_get_by_id, mock_vnf_package_vnfd_get_by_id,
|
|
mock_vnf_instance_get_by_id, mock_get_vim):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
mock_get_vim.side_effect = nfvo.VimRegionNotFoundException
|
|
|
|
body = {"flavourId": "simple",
|
|
"vimConnectionInfo": [
|
|
{'id': uuidsentinel.vim_connection_id,
|
|
'vimId': uuidsentinel.vim_id,
|
|
'vimType': 'openstack',
|
|
'accessInfo': {"region": 'region_non_existing'}}
|
|
]}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("Region not found for the VimConnection: %s" %
|
|
uuidsentinel.vim_id, resp.json['badRequest']['message'])
|
|
|
|
@mock.patch.object(vim_client.VimClient, "get_vim")
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
@mock.patch.object(objects.VnfPackageVnfd, 'get_by_id')
|
|
@mock.patch.object(objects.VnfPackage, "get_by_id")
|
|
def test_instantiate_with_default_vim_not_configured(
|
|
self, mock_vnf_package_get_by_id, mock_vnf_package_vnfd_get_by_id,
|
|
mock_vnf_instance_get_by_id, mock_get_vim):
|
|
|
|
mock_vnf_instance_get_by_id.return_value =\
|
|
fakes.return_vnf_instance_model()
|
|
mock_vnf_package_vnfd_get_by_id.return_value = \
|
|
fakes.return_vnf_package_vnfd()
|
|
mock_vnf_package_get_by_id.return_value = \
|
|
fakes.return_vnf_package_with_deployment_flavour()
|
|
mock_get_vim.side_effect = nfvo.VimDefaultNotDefined
|
|
|
|
body = {"flavourId": "simple"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("Default VIM is not defined.",
|
|
resp.json['badRequest']['message'])
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
def test_instantiate_incorrect_instantiation_state(self, mock_vnf_by_id):
|
|
vnf_instance = fakes.return_vnf_instance_model()
|
|
vnf_instance.instantiation_state = 'INSTANTIATED'
|
|
mock_vnf_by_id.return_value = vnf_instance
|
|
|
|
body = {"flavourId": "simple"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
def test_instantiate_incorrect_task_state(self, mock_vnf_by_id):
|
|
vnf_instance = fakes.return_vnf_instance_model(
|
|
task_state=fields.VnfInstanceTaskState.INSTANTIATING)
|
|
mock_vnf_by_id.return_value = vnf_instance
|
|
|
|
body = {"flavourId": "simple"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
|
expected_msg = ("Vnf instance %s in task_state INSTANTIATING. Cannot "
|
|
"instantiate while the vnf instance is in this state.")
|
|
self.assertEqual(expected_msg % uuidsentinel.vnf_instance_id,
|
|
resp.json['conflictingRequest']['message'])
|
|
|
|
@ddt.data({'attribute': 'flavourId', 'value': 123,
|
|
'expected_type': 'string'},
|
|
{'attribute': 'flavourId', 'value': True,
|
|
'expected_type': 'string'},
|
|
{'attribute': 'instantiationLevelId', 'value': 123,
|
|
'expected_type': 'string'},
|
|
{'attribute': 'instantiationLevelId', 'value': True,
|
|
'expected_type': 'string'},
|
|
{'attribute': 'additionalParams', 'value': ['val1', 'val2'],
|
|
'expected_type': 'object'},
|
|
{'attribute': 'additionalParams', 'value': True,
|
|
'expected_type': 'object'},
|
|
{'attribute': 'additionalParams', 'value': 123,
|
|
'expected_type': 'object'},
|
|
)
|
|
@ddt.unpack
|
|
def test_instantiate_with_invalid_request_body(
|
|
self, attribute, value, expected_type):
|
|
body = fakes.get_vnf_instantiation_request_body()
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
|
|
body.update({attribute: value})
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
exception = self.assertRaises(
|
|
exceptions.ValidationError, self.controller.instantiate,
|
|
req, body=body)
|
|
expected_message = \
|
|
("Invalid input for field/attribute {attribute}. Value: {value}. "
|
|
"{value} is not of type '{expected_type}'".
|
|
format(value=value, attribute=attribute,
|
|
expected_type=expected_type))
|
|
|
|
self.assertEqual(expected_message, exception.msg)
|
|
|
|
def test_instantiate_without_flavour_id(self):
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes({})
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("'flavourId' is a required property",
|
|
resp.json['badRequest']['message'])
|
|
|
|
def test_instantiate_invalid_request_parameter(self):
|
|
body = {"flavourId": "simple"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
|
|
# Pass invalid request parameter
|
|
body = {"flavourId": "simple"}
|
|
body.update({'additional_property': 'test_value'})
|
|
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("Additional properties are not allowed "
|
|
"('additional_property' was unexpected)",
|
|
resp.json['badRequest']['message'])
|
|
|
|
def test_instantiate_with_invalid_uuid(self):
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % constants.INVALID_UUID)
|
|
body = {"flavourId": "simple"}
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
|
self.assertEqual(
|
|
"Can not find requested vnf instance: %s" % constants.INVALID_UUID,
|
|
resp.json['itemNotFound']['message'])
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
def test_instantiate_with_non_existing_vnf_instance(
|
|
self, mock_vnf_by_id):
|
|
mock_vnf_by_id.side_effect = exceptions.VnfInstanceNotFound
|
|
body = {"flavourId": "simple"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/instantiate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call Instantiate API
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
|
self.assertEqual("Can not find requested vnf instance: %s" %
|
|
uuidsentinel.vnf_instance_id,
|
|
resp.json['itemNotFound']['message'])
|
|
|
|
@ddt.data('HEAD', 'PUT', 'DELETE', 'PATCH', 'GET')
|
|
def test_instantiate_invalid_http_method(self, method):
|
|
# Wrong HTTP method
|
|
body = fakes.get_vnf_instantiation_request_body()
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/29c770a3-02bc-4dfc-b4be-eb173ac00567/instantiate')
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = method
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
def test_show_vnf_not_instantiated(self, mock_vnf_by_id):
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s' % uuidsentinel.instance_id)
|
|
mock_vnf_by_id.return_value = fakes.return_vnf_instance_model()
|
|
expected_result = fakes.fake_vnf_instance_response()
|
|
res_dict = self.controller.show(req, uuidsentinel.instance_id)
|
|
self.assertEqual(expected_result, res_dict)
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
def test_show_vnf_instantiated(self, mock_vnf_by_id):
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s' % uuidsentinel.instance_id)
|
|
mock_vnf_by_id.return_value = fakes.return_vnf_instance(
|
|
fields.VnfInstanceState.INSTANTIATED)
|
|
expected_result = fakes.fake_vnf_instance_response(
|
|
fields.VnfInstanceState.INSTANTIATED)
|
|
res_dict = self.controller.show(req, uuidsentinel.instance_id)
|
|
self.assertEqual(expected_result, res_dict)
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
def test_show_with_non_existing_vnf_instance(self, mock_vnf_by_id):
|
|
mock_vnf_by_id.side_effect = exceptions.VnfInstanceNotFound
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s' % uuidsentinel.vnf_instance_id)
|
|
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
|
self.assertEqual("Can not find requested vnf instance: %s" %
|
|
uuidsentinel.vnf_instance_id,
|
|
resp.json['itemNotFound']['message'])
|
|
|
|
def test_show_with_invalid_uuid(self):
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s' % constants.INVALID_UUID)
|
|
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
|
self.assertEqual("Can not find requested vnf instance: %s" %
|
|
constants.INVALID_UUID, resp.json['itemNotFound']['message'])
|
|
|
|
@ddt.data('PATCH', 'HEAD', 'PUT', 'POST')
|
|
def test_show_invalid_http_method(self, http_method):
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s' % constants.UUID)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = http_method
|
|
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
@mock.patch.object(objects.VnfInstance, "save")
|
|
@mock.patch.object(VNFLcmRPCAPI, "terminate")
|
|
@ddt.data({'terminationType': 'FORCEFUL'},
|
|
{'terminationType': 'GRACEFUL'},
|
|
{'terminationType': 'GRACEFUL',
|
|
'gracefulTerminationTimeout': 10})
|
|
def test_terminate(self, body, mock_terminate, mock_save, mock_get_by_id):
|
|
vnf_instance_obj = fakes.return_vnf_instance(
|
|
fields.VnfInstanceState.INSTANTIATED)
|
|
mock_get_by_id.return_value = vnf_instance_obj
|
|
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
|
mock_terminate.assert_called_once()
|
|
|
|
@ddt.data(
|
|
{'attribute': 'terminationType', 'value': "TEST",
|
|
'expected_type': 'enum'},
|
|
{'attribute': 'terminationType', 'value': 123,
|
|
'expected_type': 'enum'},
|
|
{'attribute': 'terminationType', 'value': True,
|
|
'expected_type': 'enum'},
|
|
{'attribute': 'gracefulTerminationTimeout', 'value': True,
|
|
'expected_type': 'integer'},
|
|
{'attribute': 'gracefulTerminationTimeout', 'value': "test",
|
|
'expected_type': 'integer'}
|
|
)
|
|
@ddt.unpack
|
|
def test_terminate_with_invalid_request_body(
|
|
self, attribute, value, expected_type):
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
|
|
body = {'terminationType': 'GRACEFUL',
|
|
'gracefulTerminationTimeout': 10}
|
|
body.update({attribute: value})
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
expected_message = ("Invalid input for field/attribute {attribute}. "
|
|
"Value: {value}.".format(value=value, attribute=attribute))
|
|
|
|
exception = self.assertRaises(exceptions.ValidationError,
|
|
self.controller.terminate,
|
|
req, constants.UUID, body=body)
|
|
self.assertIn(expected_message, exception.msg)
|
|
|
|
def test_terminate_missing_termination_type(self):
|
|
body = {'gracefulTerminationTimeout': 10}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
# Call terminate API
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
self.assertEqual("'terminationType' is a required property",
|
|
resp.json['badRequest']['message'])
|
|
|
|
@ddt.data('GET', 'HEAD', 'PUT', 'DELETE', 'PATCH')
|
|
def test_terminate_invalid_http_method(self, method):
|
|
# Wrong HTTP method
|
|
body = {'terminationType': 'GRACEFUL',
|
|
'gracefulTerminationTimeout': 10}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = method
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
def test_terminate_non_existing_vnf_instance(self, mock_vnf_by_id):
|
|
body = {'terminationType': 'GRACEFUL',
|
|
'gracefulTerminationTimeout': 10}
|
|
mock_vnf_by_id.side_effect = exceptions.VnfInstanceNotFound
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.NOT_FOUND, resp.status_code)
|
|
self.assertEqual("Can not find requested vnf instance: %s" %
|
|
uuidsentinel.vnf_instance_id,
|
|
resp.json['itemNotFound']['message'])
|
|
|
|
@mock.patch.object(objects.vnf_instance, "_vnf_instance_get_by_id")
|
|
def test_terminate_incorrect_instantiation_state(self, mock_vnf_by_id):
|
|
mock_vnf_by_id.return_value = fakes.return_vnf_instance()
|
|
body = {"terminationType": "FORCEFUL"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
|
expected_msg = ("Vnf instance %s in instantiation_state "
|
|
"NOT_INSTANTIATED. Cannot terminate while the vnf "
|
|
"instance is in this state.")
|
|
self.assertEqual(expected_msg % uuidsentinel.vnf_instance_id,
|
|
resp.json['conflictingRequest']['message'])
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
def test_terminate_incorrect_task_state(self, mock_vnf_by_id):
|
|
vnf_instance = fakes.return_vnf_instance(
|
|
instantiated_state=fields.VnfInstanceState.INSTANTIATED,
|
|
task_state=fields.VnfInstanceTaskState.TERMINATING)
|
|
mock_vnf_by_id.return_value = vnf_instance
|
|
|
|
body = {"terminationType": "FORCEFUL"}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/terminate' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
|
expected_msg = ("Vnf instance %s in task_state TERMINATING. Cannot "
|
|
"terminate while the vnf instance is in this state.")
|
|
self.assertEqual(expected_msg % uuidsentinel.vnf_instance_id,
|
|
resp.json['conflictingRequest']['message'])
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
@mock.patch.object(objects.VnfInstance, "save")
|
|
@mock.patch.object(VNFLcmRPCAPI, "heal")
|
|
@ddt.data({'cause': 'healing'}, {})
|
|
def test_heal(self, body, mock_rpc_heal, mock_save,
|
|
mock_vnf_by_id):
|
|
vnf_instance_obj = fakes.return_vnf_instance(
|
|
fields.VnfInstanceState.INSTANTIATED)
|
|
mock_vnf_by_id.return_value = vnf_instance_obj
|
|
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.ACCEPTED, resp.status_code)
|
|
mock_rpc_heal.assert_called_once()
|
|
|
|
def test_heal_cause_max_length_exceeded(self):
|
|
body = {'cause': 'A' * 256}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
def test_heal_incorrect_instantiated_state(self, mock_vnf_by_id):
|
|
vnf_instance_obj = fakes.return_vnf_instance(
|
|
fields.VnfInstanceState.NOT_INSTANTIATED)
|
|
mock_vnf_by_id.return_value = vnf_instance_obj
|
|
|
|
body = {}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
|
expected_msg = ("Vnf instance %s in instantiation_state "
|
|
"NOT_INSTANTIATED. Cannot heal while the vnf instance "
|
|
"is in this state.")
|
|
self.assertEqual(expected_msg % uuidsentinel.vnf_instance_id,
|
|
resp.json['conflictingRequest']['message'])
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
def test_heal_incorrect_task_state(self, mock_vnf_by_id):
|
|
vnf_instance_obj = fakes.return_vnf_instance(
|
|
fields.VnfInstanceState.INSTANTIATED,
|
|
task_state=fields.VnfInstanceTaskState.HEALING)
|
|
mock_vnf_by_id.return_value = vnf_instance_obj
|
|
|
|
body = {}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.CONFLICT, resp.status_code)
|
|
expected_msg = ("Vnf instance %s in task_state "
|
|
"HEALING. Cannot heal while the vnf instance "
|
|
"is in this state.")
|
|
self.assertEqual(expected_msg % uuidsentinel.vnf_instance_id,
|
|
resp.json['conflictingRequest']['message'])
|
|
|
|
@mock.patch.object(objects.VnfInstance, "get_by_id")
|
|
def test_heal_with_invalid_vnfc_id(self, mock_vnf_by_id):
|
|
vnf_instance_obj = fakes.return_vnf_instance(
|
|
fields.VnfInstanceState.INSTANTIATED)
|
|
mock_vnf_by_id.return_value = vnf_instance_obj
|
|
|
|
body = {'vnfcInstanceId': [uuidsentinel.vnfc_instance_id]}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
|
|
resp = req.get_response(self.app)
|
|
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
|
|
expected_msg = "Vnfc id %s not present in vnf instance %s"
|
|
self.assertEqual(expected_msg % (uuidsentinel.vnfc_instance_id,
|
|
uuidsentinel.vnf_instance_id), resp.json['badRequest']['message'])
|
|
|
|
@ddt.data('HEAD', 'PUT', 'DELETE', 'PATCH', 'GET')
|
|
def test_heal_invalid_http_method(self, method):
|
|
body = {}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/%s/heal' % uuidsentinel.vnf_instance_id)
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = method
|
|
|
|
resp = req.get_response(self.app)
|
|
|
|
self.assertEqual(http_client.METHOD_NOT_ALLOWED, resp.status_code)
|
|
|
|
@ddt.data({'attribute': 'cause', 'value': 123,
|
|
'expected_type': 'string'},
|
|
{'attribute': 'cause', 'value': True,
|
|
'expected_type': 'string'},
|
|
{'attribute': 'vnfcInstanceId', 'value': 123,
|
|
'expected_type': 'array'},
|
|
{'attribute': 'vnfcInstanceId', 'value': True,
|
|
'expected_type': 'array'},
|
|
)
|
|
@ddt.unpack
|
|
def test_heal_with_invalid_request_body(
|
|
self, attribute, value, expected_type):
|
|
body = {}
|
|
req = fake_request.HTTPRequest.blank(
|
|
'/vnf_instances/29c770a3-02bc-4dfc-b4be-eb173ac00567/heal')
|
|
body.update({attribute: value})
|
|
req.body = jsonutils.dump_as_bytes(body)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
req.method = 'POST'
|
|
exception = self.assertRaises(
|
|
exceptions.ValidationError, self.controller.heal,
|
|
req, body=body)
|
|
expected_message = \
|
|
("Invalid input for field/attribute {attribute}. Value: {value}. "
|
|
"{value} is not of type '{expected_type}'".
|
|
format(value=value, attribute=attribute,
|
|
expected_type=expected_type))
|
|
|
|
self.assertEqual(expected_message, exception.msg)
|