Tacker: ETSI MANO NFV Orchestrator / VNF Manager. See https://wiki.openstack.org/wiki/Tacker
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
tacker/tacker/tests/unit/vnfpkgm/test_controller.py

944 lines
44 KiB

# Copyright (C) 2019 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 six.moves import urllib
from webob import exc
from tacker.api.vnfpkgm.v1 import controller
from tacker.common import exceptions as tacker_exc
from tacker.conductor.conductorrpc.vnf_pkgm_rpc import VNFPackageRPCAPI
from tacker.glance_store import store as glance_store
from tacker import objects
from tacker.objects import fields
from tacker.objects import vnf_package
from tacker.objects.vnf_package import VnfPackagesList
from tacker.objects.vnf_software_image import VnfSoftwareImage
from tacker.tests import constants
from tacker.tests.unit import base
from tacker.tests.unit import fake_request
from tacker.tests.unit.vnfpkgm import fakes
@ddt.ddt
class TestController(base.TestCase):
def setUp(self):
super(TestController, self).setUp()
self.controller = controller.VnfPkgmController()
@property
def app(self):
return fakes.wsgi_app_v1()
@mock.patch.object(vnf_package, '_vnf_package_create')
@mock.patch.object(vnf_package.VnfPackage, '_from_db_object')
def test_create_with_status_202(self, mock_from_db, mock_vnf_pack):
body = {'userDefinedData': {'abc': 'xyz'}}
req = fake_request.HTTPRequest.blank('/vnf_packages')
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.CREATED, resp.status_code)
@mock.patch.object(vnf_package, '_vnf_package_create')
@mock.patch.object(vnf_package.VnfPackage, '_from_db_object')
def test_create_without_userdefine_data(self, mock_from_db,
mock_vnf_pack):
body = {'userDefinedData': {}}
req = fake_request.HTTPRequest.blank('/vnf_packages')
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.CREATED, resp.status_code)
@mock.patch.object(VnfSoftwareImage, 'get_by_id')
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_show(self, mock_vnf_by_id, mock_sw_image_by_id):
req = fake_request.HTTPRequest.blank(
'/vnfpkgm/v1/vnf_packages/%s' % constants.UUID)
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj()
mock_sw_image_by_id.return_value = fakes.return_software_image()
expected_result = fakes.VNFPACKAGE_RESPONSE
res_dict = self.controller.show(req, constants.UUID)
self.assertEqual(expected_result, res_dict)
def test_show_with_invalid_uuid(self):
req = fake_request.HTTPRequest.blank(
'/vnfpkgm/v1/vnf_packages/%s' % constants.INVALID_UUID)
self.assertRaises(exc.HTTPNotFound, self.controller.show,
req, constants.INVALID_UUID)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_show_no_vnf_package(self, mock_vnf_by_id):
req = fake_request.HTTPRequest.blank(
'/vnfpkgm/v1/vnf_packages/%s' % constants.UUID)
msg = _("Can not find requested vnf package: %s") % constants.UUID
mock_vnf_by_id.side_effect = exc.HTTPNotFound(explanation=msg)
self.assertRaises(exc.HTTPNotFound, self.controller.show,
req, constants.UUID)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data('/vnfpkgm/v1/vnf_packages')
def test_index(self, path, mock_vnf_list):
req = fake_request.HTTPRequest.blank(path)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response(remove_attrs=[
'softwareImages', 'checksum', 'userDefinedData'])
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
def test_index_attribute_selector_all_fields(self, mock_vnf_list):
params = {'all_fields': ''}
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response()
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
def test_index_attribute_selector_exclude_default(self, mock_vnf_list):
params = {'exclude_default': ''}
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response(remove_attrs=[
'softwareImages', 'checksum', 'userDefinedData'])
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'exclude_fields': 'softwareImages'},
{'exclude_fields': 'checksum'},
{'exclude_fields': 'userDefinedData'},
)
def test_index_attribute_selector_exclude_fields(self, params,
mock_vnf_list):
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
remove_attrs = [params['exclude_fields']]
expected_result = fakes.index_response(remove_attrs=remove_attrs)
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'fields': 'softwareImages'},
{'fields': 'checksum'},
{'fields': 'userDefinedData'},
)
def test_index_attribute_selector_fields(self, params, mock_vnf_list):
"""Test valid attribute names with fields parameter
We can specify complex attributes in fields. Hence the data only
contains such attributes.
"""
complex_attrs = ['softwareImages', 'checksum', 'userDefinedData']
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
remove_attrs = [x for x in complex_attrs if x != params['fields']]
expected_result = fakes.index_response(remove_attrs=remove_attrs)
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
def test_index_attribute_selector_user_defined_data_combination(self,
mock_vnf_list):
"""Query user defined data with fields parameter
This test queries combination of user defined data. i.e. fields of
different complex attributes.
"""
params = {
'fields': 'userDefinedData/key1,softwareImages/userMetadata/key3',
}
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
vnf_package_updates = {
'userDefinedData': {'key1': 'value1'},
'softwareImages': [{'userMetadata': {'key3': 'value3'}}]
}
expected_result = fakes.index_response(remove_attrs=[
'checksum'], vnf_package_updates=vnf_package_updates)
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
def test_index_attribute_selector_user_defined_data(self, mock_vnf_list):
params = {'fields': 'userDefinedData/key1,userDefinedData/key2'}
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response(remove_attrs=[
'checksum', 'softwareImages'])
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
def test_index_attribute_selector_nested_complex_attribute(self,
mock_vnf_list):
params = {'fields': 'softwareImages/checksum/algorithm,'
'softwareImages/minRam'}
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
vnf_package_updates = {
'softwareImages': [{
'minRam': 0,
'checksum': {'algorithm': 'fake-algorithm'}
}]
}
expected_result = fakes.index_response(remove_attrs=[
'checksum', 'userDefinedData'],
vnf_package_updates=vnf_package_updates)
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': '(eq,vnfdId,dummy_vnfd_id)'},
{'filter': '(in,vnfdId,dummy_vnfd_id)'},
{'filter': '(cont,vnfdId,dummy_vnfd_id)'},
{'filter': '(neq,vnfdId,dummy_vnfd_id)'},
{'filter': '(nin,vnfdId,dummy_vnfd_id)'},
{'filter': '(ncont,vnfdId,dummy_vnfd_id)'},
{'filter': '(gt,softwareImages/createdAt,2020-03-11 04:10:15+00:00)'},
{'filter': '(gte,softwareImages/createdAt,2020-03-14 04:10:15+00:00)'},
{'filter': '(lt,softwareImages/createdAt,2020-03-20 04:10:15+00:00)'},
{'filter': '(lte,softwareImages/createdAt,2020-03-11 04:10:15+00:00)'},
)
def test_index_filter_operator(self, filter_params, mock_vnf_list):
"""Tests all supported operators in filter expression """
query = urllib.parse.urlencode(filter_params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response(remove_attrs=[
'softwareImages', 'checksum', 'userDefinedData'])
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
def test_index_filter_combination(self, mock_vnf_list):
"""Test multiple filter parameters separated by semicolon """
params = {'filter': '(eq,vnfdId,dummy_vnfd_id);(eq,id,dummy_id)'}
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response(remove_attrs=[
'softwareImages', 'checksum', 'userDefinedData'])
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': '(eq,id,dummy_value)'},
{'filter': '(eq,vnfdId,dummy_value)'},
{'filter': '(eq,onboardingState,ONBOARDED)'},
{'filter': '(eq,operationalState,ENABLED)'},
{'filter': '(eq,usageState,NOT_IN_USE)'},
{'filter': '(eq,vnfProvider,dummy_value)'},
{'filter': '(eq,vnfProductName,dummy_value)'},
{'filter': '(eq,vnfSoftwareVersion,dummy_value)'},
{'filter': '(eq,vnfdVersion,dummy_value)'},
{'filter': '(eq,userDefinedData/key1,dummy_value)'},
{'filter': '(eq,checksum/algorithm,dummy_value)'},
{'filter': '(eq,checksum/hash,dummy_value)'},
{'filter': '(eq,softwareImages/id,dummy_value)'},
{'filter': '(eq,softwareImages/imagePath,dummy_value)'},
{'filter': '(eq,softwareImages/diskFormat,dummy_value)'},
{'filter': '(eq,softwareImages/userMetadata/key3,dummy_value)'},
{'filter': '(eq,softwareImages/size,0)'},
{'filter': '(gt,softwareImages/createdAt,2020-03-14 04:10:15+00:00)'},
{'filter': '(eq,softwareImages/name,dummy_value)'},
{'filter': '(eq,softwareImages/minDisk,0)'},
{'filter': '(eq,softwareImages/version,dummy_value)'},
{'filter': '(eq,softwareImages/provider,dummy_value)'},
{'filter': '(eq,softwareImages/minRam,0)'},
{'filter': '(eq,softwareImages/containerFormat,dummy_value)'},
{'filter': '(eq,softwareImages/checksum/hash,dummy_value)'},
{'filter': '(eq,softwareImages/checksum/algorithm,dummy_value)'},
)
def test_index_filter_attributes(self, filter_params, mock_vnf_list):
"""Test various attributes supported for filter parameter """
query = urllib.parse.urlencode(filter_params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response(remove_attrs=[
'softwareImages', 'checksum', 'userDefinedData'])
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': "(eq,vnfProductName,dummy_value)"},
{'filter': "(eq,vnfProductName,dummy value)"},
{'filter': "(eq,vnfProductName,'dummy value')"},
{'filter': "(eq,vnfProductName,'dummy (hi) value')"},
{'filter': "(eq,vnfProductName,'dummy ''hi'' value')"},
{'filter': "(eq,vnfProductName,'''dummy ''hi'' value''')"},
)
def test_index_filter_valid_string_values(self, filter_params,
mock_vnf_list):
"""Tests all the supported string values.
For example:
- values which are not enclosed in single quotes
- values which are enclosed in single quotes
- values having single quotes within them
- values having round brackets in them
"""
query = urllib.parse.urlencode(filter_params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
res_dict = self.controller.index(req)
expected_result = fakes.index_response(remove_attrs=[
'softwareImages', 'checksum', 'userDefinedData'])
self.assertEqual(expected_result, res_dict)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': "(eq,vnfProductName,value"},
{'filter': "eq,vnfProductName,value)"},
{'filter': "(eq,vnfProductName,value);"},
{'filter': "(eq , vnfProductName ,value)"},
)
def test_index_filter_invalid_expression(self, filter_params,
mock_vnf_list):
"""Test invalid filter expression """
query = urllib.parse.urlencode(filter_params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': "(eq,vnfProductName,singl'quote)"},
{'filter': "(eq,vnfProductName,three''' quotes)"},
{'filter': "(eq,vnfProductName,round ) bracket)"},
{'filter': "(eq,vnfProductName,'dummy 'hi' value')"},
{'filter': "(eq,vnfProductName,'dummy's value')"},
{'filter': "(eq,vnfProductName,'three ''' quotes')"},
)
def test_index_filter_invalid_string_values(self, filter_params,
mock_vnf_list):
"""Test invalid string values as per ETSI NFV SOL013 5.2.2 """
query = urllib.parse.urlencode(filter_params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': '(eq,vnfdId,value1,value2)'},
{'filter': '(fake,vnfdId,dummy_vnfd_id)'},
{'filter': '(,vnfdId,dummy_vnfd_id)'},
)
def test_index_filter_invalid_operator(self, params, mock_vnf_list):
"""Test invalid operator in filter expression """
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': '(eq,fakeattr,fakevalue)'},
{'filter': '(eq,,fakevalue)'},
)
def test_index_filter_invalid_attribute(self, params, mock_vnf_list):
"""Test invalid attribute in filter expression """
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'filter': '(eq,operationalState,fake_value)'},
{'filter': '(eq,softwareImages/size,fake_value)'},
{'filter': '(gt,softwareImages/createdAt,fake_value)'},
{'filter': '(eq,softwareImages/minDisk,fake_value)'},
{'filter': '(eq,softwareImages/minRam,fake_value)'},
)
def test_index_filter_invalid_value_type(self, filter_params,
mock_vnf_list):
"""Test values which doesn't match with attribute data type """
query = urllib.parse.urlencode(filter_params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'fields': 'nonExistentField'},
{'exclude_fields': 'nonExistentField'}
)
def test_index_attribute_selector_invalid_fields(self, params,
mock_vnf_list):
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'fields': 'softwareImages', 'all_fields': ''},
{'exclude_fields': 'checksum', 'all_fields': ''},
{'fields': 'softwareImages', 'exclude_fields': 'checksum'}
)
def test_index_attribute_selector_invalid_combination(self, params,
mock_vnf_list):
"""Test invalid combination of attribute selector parameters """
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(VnfPackagesList, "get_by_filters")
@ddt.data(
{'exclude_default': 'softwareImages'},
{'all_fields': 'checksum'},
)
def test_index_attribute_selector_unexpected_value(self, params,
mock_vnf_list):
"""Test values with the parameters which doesn't need values. """
query = urllib.parse.urlencode(params)
req = fake_request.HTTPRequest.blank('/vnfpkgm/v1/vnf_packages?' +
query)
mock_vnf_list.return_value = fakes.return_vnf_package_list()
self.assertRaises(tacker_exc.ValidationError, self.controller.index,
req)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
@mock.patch.object(VNFPackageRPCAPI, "delete_vnf_package")
def test_delete_with_204_status(self, mock_delete_rpc, mock_vnf_by_id):
vnfpkg_updates = {'operational_state': 'DISABLED'}
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj(
vnf_package_updates=vnfpkg_updates)
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s' % constants.UUID)
req.headers['Content-Type'] = 'application/json'
req.method = 'DELETE'
resp = req.get_response(self.app)
self.assertEqual(http_client.NO_CONTENT, resp.status_code)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_delete_no_vnf_package(self, mock_vnf_by_id):
req = fake_request.HTTPRequest.blank(
'/vnfpkgm/v1/vnf_packages/%s' % constants.UUID)
msg = _("Can not find requested vnf package: %s") % constants.UUID
mock_vnf_by_id.side_effect = exc.HTTPNotFound(explanation=msg)
self.assertRaises(exc.HTTPNotFound, self.controller.delete,
req, constants.UUID)
def test_delete_with_invalid_uuid(self):
req = fake_request.HTTPRequest.blank(
'/vnfpkgm/v1/vnf_packages/%s' % constants.INVALID_UUID)
self.assertRaises(exc.HTTPNotFound, self.controller.delete,
req, constants.INVALID_UUID)
@mock.patch.object(objects.VnfPackage, "get_by_id")
def test_delete_with_operational_state_enabled(self, mock_vnf_by_id):
req = fake_request.HTTPRequest.blank(
'/vnfpkgm/v1/vnf_packages/%s' % constants.UUID)
vnf_package_dict = fakes.fake_vnf_package()
vnf_package_dict['operational_state'] = \
fields.PackageOperationalStateType.ENABLED
vnf_package = objects.VnfPackage(**vnf_package_dict)
mock_vnf_by_id.return_value = vnf_package
self.assertRaises(exc.HTTPConflict, self.controller.delete,
req, constants.UUID)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_delete_with_usage_state_in_use(self, mock_vnf_by_id):
req = fake_request.HTTPRequest.blank(
'/vnfpkgm/v1/vnf_packages/%s' % constants.UUID)
vnf_package_dict = fakes.fake_vnf_package()
vnf_package_dict['usage_state'] = \
fields.PackageUsageStateType.IN_USE
vnf_package = objects.VnfPackage(**vnf_package_dict)
mock_vnf_by_id.return_value = vnf_package
self.assertRaises(exc.HTTPConflict, self.controller.delete,
req, constants.UUID)
@mock.patch.object(glance_store, 'store_csar')
@mock.patch.object(VNFPackageRPCAPI, "upload_vnf_package_content")
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
@mock.patch.object(vnf_package.VnfPackage, "save")
def test_upload_vnf_package_content(self, mock_vnf_pack_save,
mock_vnf_by_id,
mock_upload_vnf_package_content,
mock_glance_store):
file_path = "tacker/tests/etc/samples/test_data.zip"
file_obj = open(file_path, "rb")
updates = {'onboarding_state': 'CREATED',
'operational_state': 'DISABLED'}
vnf_package_dict = fakes.fake_vnf_package(updates)
vnf_package_obj = objects.VnfPackage(**vnf_package_dict)
mock_vnf_by_id.return_value = vnf_package_obj
mock_vnf_pack_save.return_value = vnf_package_obj
mock_glance_store.return_value = 'location', 0, 'checksum',\
'multihash', 'loc_meta'
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content'
% constants.UUID)
req.headers['Content-Type'] = 'application/zip'
req.method = 'PUT'
req.body = jsonutils.dump_as_bytes(file_obj)
resp = req.get_response(self.app)
mock_glance_store.assert_called()
self.assertEqual(http_client.ACCEPTED, resp.status_code)
def test_upload_vnf_package_content_with_invalid_uuid(self):
file_path = "tacker/tests/etc/samples/test_data.zip"
file_obj = open(file_path, "rb")
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content'
% constants.INVALID_UUID)
exception = self.assertRaises(exc.HTTPNotFound,
self.controller.upload_vnf_package_content,
req, constants.INVALID_UUID, body=file_obj)
self.assertEqual(
"Can not find requested vnf package: %s" % constants.INVALID_UUID,
exception.explanation)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_upload_vnf_package_content_without_vnf_pack(self,
mock_vnf_by_id):
file_path = "tacker/tests/etc/samples/test_data.zip"
file_obj = open(file_path, "rb")
msg = _("Can not find requested vnf package: %s") % constants.UUID
mock_vnf_by_id.side_effect = exc.HTTPNotFound(explanation=msg)
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content' % constants.UUID)
exception = self.assertRaises(
exc.HTTPNotFound, self.controller.upload_vnf_package_content,
req, constants.UUID, body=file_obj)
self.assertEqual(
"Can not find requested vnf package: %s" % constants.UUID,
exception.explanation)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_upload_vnf_package_content_with_invalid_status(self,
mock_vnf_by_id):
file_path = "tacker/tests/etc/samples/test_data.zip"
file_obj = open(file_path, "rb")
vnf_obj = fakes.return_vnfpkg_obj()
vnf_obj.__setattr__('onboarding_state', 'ONBOARDED')
mock_vnf_by_id.return_value = vnf_obj
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content' % constants.UUID)
self.assertRaises(exc.HTTPConflict,
self.controller.upload_vnf_package_content,
req, constants.UUID, body=file_obj)
@mock.patch.object(urllib.request, 'urlopen')
@mock.patch.object(VNFPackageRPCAPI, "upload_vnf_package_from_uri")
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
@mock.patch.object(vnf_package.VnfPackage, "save")
def test_upload_vnf_package_from_uri(self, mock_vnf_pack_save,
mock_vnf_by_id,
mock_upload_vnf_package_from_uri,
mock_url_open):
body = {"addressInformation": "http://localhost/test_data.zip"}
updates = {'onboarding_state': 'CREATED',
'operational_state': 'DISABLED'}
vnf_package_dict = fakes.fake_vnf_package(updates)
vnf_package_obj = objects.VnfPackage(**vnf_package_dict)
mock_vnf_by_id.return_value = vnf_package_obj
mock_vnf_pack_save.return_value = vnf_package_obj
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/upload_from_uri'
% constants.UUID)
req.headers['Content-Type'] = 'application/json'
req.method = 'POST'
req.body = jsonutils.dump_as_bytes(body)
resp = req.get_response(self.app)
self.assertEqual(http_client.ACCEPTED, resp.status_code)
def test_upload_vnf_package_from_uri_with_invalid_uuid(self):
body = {"addressInformation": "http://localhost/test_data.zip"}
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/upload_from_uri'
% constants.INVALID_UUID)
self.assertRaises(exc.HTTPNotFound,
self.controller.upload_vnf_package_from_uri,
req, constants.INVALID_UUID, body=body)
@mock.patch.object(urllib.request, 'urlopen')
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_upload_vnf_package_from_uri_without_vnf_pack(self,
mock_vnf_by_id,
mock_url_open):
body = {"addressInformation": "http://localhost/test_data.zip"}
msg = _("Can not find requested vnf package: %s") % constants.UUID
mock_vnf_by_id.side_effect = exc.HTTPNotFound(explanation=msg)
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/upload_from_uri'
% constants.UUID)
self.assertRaises(exc.HTTPNotFound,
self.controller.upload_vnf_package_from_uri,
req, constants.UUID, body=body)
@mock.patch.object(urllib.request, 'urlopen')
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_upload_vnf_package_from_uri_with_invalid_status(self,
mock_vnf_by_id,
mock_url_open):
body = {"addressInformation": "http://localhost/test_data.zip"}
vnf_obj = fakes.return_vnfpkg_obj()
vnf_obj.__setattr__('onboarding_state', 'ONBOARDED')
mock_vnf_by_id.return_value = vnf_obj
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/upload_from_uri'
% constants.UUID)
self.assertRaises(exc.HTTPConflict,
self.controller.upload_vnf_package_from_uri,
req, constants.UUID, body=body)
@ddt.data("http://test_data.zip", "xyz://github.com/abc/xyz.git",
"xyz://github.com/abc/xyz")
def test_upload_vnf_package_from_uri_with_invalid_url(self, invalid_url):
body = {"addressInformation": invalid_url}
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/upload_from_uri'
% constants.UUID)
self.assertRaises(exc.HTTPBadRequest,
self.controller.upload_vnf_package_from_uri,
req, constants.UUID, body=body)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
@mock.patch.object(vnf_package.VnfPackage, "save")
def test_patch(self, mock_save, mock_vnf_by_id):
vnf_package_updates = {'operational_state': 'DISABLED'}
mock_vnf_by_id.return_value = \
fakes.return_vnfpkg_obj(vnf_package_updates=vnf_package_updates)
req_body = {"operationalState": "ENABLED",
"userDefinedData": {"testKey1": "val01",
"testKey2": "val02", "testkey3": "val03"}}
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s'
% constants.UUID)
req.headers['Content-Type'] = 'application/json'
req.method = 'PATCH'
req.body = jsonutils.dump_as_bytes(req_body)
resp = req.get_response(self.app)
self.assertEqual(http_client.OK, resp.status_code)
self.assertEqual(req_body, jsonutils.loads(resp.body))
def test_patch_with_empty_body(self):
body = {}
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s'
% constants.UUID)
req.headers['Content-Type'] = 'application/json'
req.method = 'PATCH'
req.body = jsonutils.dump_as_bytes(body)
resp = req.get_response(self.app)
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
def test_patch_with_invalid_operational_state(self):
body = {"operationalState": "DISABLE"}
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s'
% constants.UUID)
req.headers['Content-Type'] = 'application/json'
req.method = 'PATCH'
req.body = jsonutils.dump_as_bytes(body)
resp = req.get_response(self.app)
self.assertEqual(http_client.BAD_REQUEST, resp.status_code)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
@mock.patch.object(vnf_package.VnfPackage, "save")
def test_patch_update_existing_user_data(self, mock_save, mock_vnf_by_id):
fake_obj = fakes.return_vnfpkg_obj(vnf_package_updates={
"operational_state": "DISABLED", "onboarding_state": "CREATED",
"user_data": {"testKey1": "val01", "testKey2": "val02",
"testKey3": "val03"}})
mock_vnf_by_id.return_value = fake_obj
req_body = {"userDefinedData": {"testKey1": "changed_val01",
"testKey2": "changed_val02",
"testKey3": "changed_val03"}}
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s'
% constants.UUID)
req.headers['Content-Type'] = 'application/json'
req.method = 'PATCH'
req.body = jsonutils.dump_as_bytes(req_body)
resp = req.get_response(self.app)
self.assertEqual(http_client.OK, resp.status_code)
self.assertEqual(req_body, jsonutils.loads(resp.body))
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
@mock.patch.object(vnf_package.VnfPackage, "save")
def test_patch_failed_with_same_user_data(self, mock_save,
mock_vnf_by_id):
vnf_package_updates = {"operational_state": "DISABLED",
"onboarding_state": "CREATED",
"user_data": {"testKey1": "val01",
"testKey2": "val02",
"testkey3": "val03"}}
req_body = {"userDefinedData": {"testKey1": "val01",
"testKey2": "val02",
"testkey3": "val03"}}
fake_obj = fakes.return_vnfpkg_obj(
vnf_package_updates=vnf_package_updates)
mock_vnf_by_id.return_value = fake_obj
req = fake_request.HTTPRequest.blank('/vnf_packages/%s'
% constants.UUID)
self.assertRaises(exc.HTTPConflict,
self.controller.patch,
req, constants.UUID, body=req_body)
def test_patch_with_invalid_uuid(self):
body = {"operationalState": "ENABLED"}
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s'
% constants.INVALID_UUID)
exception = self.assertRaises(exc.HTTPNotFound,
self.controller.patch,
req, constants.INVALID_UUID, body=body)
self.assertEqual(
"Can not find requested vnf package: %s" % constants.INVALID_UUID,
exception.explanation)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_patch_with_non_existing_vnf_package(self, mock_vnf_by_id):
body = {"operationalState": "ENABLED"}
msg = _("Can not find requested vnf package: %s") % constants.UUID
mock_vnf_by_id.side_effect = exc.HTTPNotFound(explanation=msg)
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s' % constants.UUID)
exception = self.assertRaises(
exc.HTTPNotFound, self.controller.patch,
req, constants.UUID, body=body)
self.assertEqual(
"Can not find requested vnf package: %s" % constants.UUID,
exception.explanation)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_patch_failed_with_same_operational_state(self, mock_vnf_by_id):
vnf_package_updates = {'operational_state': 'DISABLED'}
mock_vnf_by_id.return_value = \
fakes.return_vnfpkg_obj(vnf_package_updates=vnf_package_updates)
body = {"operationalState": "DISABLED",
"userDefinedData": {"testKey1": "val01",
"testKey2": "val02", "testkey3": "val03"}}
req = fake_request.HTTPRequest.blank('/vnf_packages/%s'
% constants.UUID)
self.assertRaises(exc.HTTPConflict,
self.controller.patch,
req, constants.UUID, body=body)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_patch_not_in_onboarded_state(self, mock_vnf_by_id):
vnf_package_updates = {'onboarding_state': 'CREATED',
'operational_state': 'DISABLED'}
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj(
vnf_package_updates=vnf_package_updates)
body = {"operationalState": "DISABLED"}
req = fake_request.HTTPRequest.blank('/vnf_packages/%s'
% constants.UUID)
self.assertRaises(exc.HTTPBadRequest,
self.controller.patch,
req, constants.UUID, body=body)
@mock.patch.object(VNFPackageRPCAPI, "get_vnf_package_vnfd")
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
@ddt.data('application/zip', 'text/plain,application/zip',
'application/zip,text/plain')
def test_get_vnf_package_vnfd_with_valid_accept_headers(
self, accept_headers, mock_vnf_by_id, mock_get_vnf_package_vnfd):
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj()
mock_get_vnf_package_vnfd.return_value = fakes.return_vnfd_data()
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.UUID)
req.headers['Accept'] = accept_headers
req.method = 'GET'
resp = req.get_response(self.app)
self.assertEqual(http_client.OK, resp.status_code)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_get_vnf_package_vnfd_with_invalid_accept_header(
self, mock_vnf_by_id):
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj()
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.UUID)
req.headers['Accept'] = 'test-invalid-header'
req.method = 'GET'
self.assertRaises(exc.HTTPNotAcceptable,
self.controller.get_vnf_package_vnfd,
req, constants.UUID)
@mock.patch.object(VNFPackageRPCAPI, "get_vnf_package_vnfd")
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_get_vnf_package_vnfd_failed_with_bad_request(
self, mock_vnf_by_id, mock_get_vnf_package_vnfd):
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj()
mock_get_vnf_package_vnfd.return_value = fakes.return_vnfd_data()
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.UUID)
req.headers['Accept'] = 'text/plain'
req.method = 'GET'
self.assertRaises(exc.HTTPBadRequest,
self.controller.get_vnf_package_vnfd,
req, constants.UUID)
@mock.patch.object(VNFPackageRPCAPI, "get_vnf_package_vnfd")
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_get_vnf_package_vnfd_for_content_type_text_plain(self,
mock_vnf_by_id,
mock_get_vnf_package_vnfd):
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj()
fake_vnfd_data = fakes.return_vnfd_data(multiple_yaml_files=False)
mock_get_vnf_package_vnfd.return_value = fake_vnfd_data
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.UUID)
req.headers['Accept'] = 'text/plain'
req.method = 'GET'
resp = req.get_response(self.app)
self.assertEqual(http_client.OK, resp.status_code)
self.assertEqual('text/plain', resp.content_type)
self.assertEqual(fake_vnfd_data[list(fake_vnfd_data.keys())[0]],
resp.text)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_get_vnf_package_vnfd_failed_with_invalid_status(
self, mock_vnf_by_id):
vnf_package_updates = {
'onboarding_state': 'CREATED',
'operational_state': 'DISABLED'
}
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj(
vnf_package_updates=vnf_package_updates)
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.UUID)
req.headers['Accept'] = 'application/zip'
req.method = 'GET'
resp = req.get_response(self.app)
self.assertEqual(http_client.CONFLICT, resp.status_code)
def test_get_vnf_package_vnfd_with_invalid_uuid(self):
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.INVALID_UUID)
req.headers['Accept'] = 'application/zip'
req.method = 'GET'
exception = self.assertRaises(exc.HTTPNotFound,
self.controller.get_vnf_package_vnfd,
req, constants.INVALID_UUID)
self.assertEqual(
"Can not find requested vnf package: %s" % constants.INVALID_UUID,
exception.explanation)
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_get_vnf_package_vnfd_with_non_existing_vnf_packagee(
self, mock_vnf_by_id):
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.UUID)
req.headers['Accept'] = 'application/zip'
req.method = 'GET'
mock_vnf_by_id.side_effect = tacker_exc.VnfPackageNotFound
self.assertRaises(exc.HTTPNotFound,
self.controller.get_vnf_package_vnfd, req,
constants.UUID)
@mock.patch.object(VNFPackageRPCAPI, "get_vnf_package_vnfd")
@mock.patch.object(vnf_package.VnfPackage, "get_by_id")
def test_get_vnf_package_vnfd_failed_with_internal_server_error(
self, mock_vnf_by_id, mock_get_vnf_package_vnfd):
mock_vnf_by_id.return_value = fakes.return_vnfpkg_obj()
mock_get_vnf_package_vnfd.side_effect = tacker_exc.FailedToGetVnfdData
req = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/vnfd'
% constants.UUID)
req.headers['Accept'] = 'application/zip'
req.method = 'GET'
resp = req.get_response(self.app)
self.assertRaises(exc.HTTPInternalServerError,
self.controller.get_vnf_package_vnfd,
req, constants.UUID)
self.assertEqual(http_client.INTERNAL_SERVER_ERROR, resp.status_code)
def test_fetch_vnf_package_content_valid_range(self):
request = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/')
request.headers["Range"] = 'bytes=10-99'
range_ = self.controller._get_range_from_request(request, 120)
self.assertEqual(10, range_.start)
self.assertEqual(100, range_.end) # non-inclusive
def test_fetch_vnf_package_content_invalid_range(self):
request = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/')
request.headers["Range"] = 'bytes=150-'
self.assertRaises(exc.HTTPRequestRangeNotSatisfiable,
self.controller._get_range_from_request,
request, 120)
def test_fetch_vnf_package_content_invalid_multiple_range(self):
request = fake_request.HTTPRequest.blank(
'/vnf_packages/%s/package_content/')
request.headers["Range"] = 'bytes=10-20,21-30'
self.assertRaises(exc.HTTPBadRequest,
self.controller._get_range_from_request, request,
120)