From: erlei Date: Mon, 12 Aug 2019 13:20:53 +0000 (+0800) Subject: ADD UT Issue-ID: VFC-1429 Signed-off-by: zhuerlei X-Git-Tag: 1.3.7~62^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=59fde50a7cfdf31b03cd183caafa7d384789cf56;p=vfc%2Fnfvo%2Flcm.git ADD UT Issue-ID: VFC-1429 Signed-off-by: zhuerlei Change-Id: I0a7bb0513ab687a65cc95ec7f4537a603fa0b2c9 Signed-off-by: erlei --- diff --git a/lcm/ns/tests/__init__.py b/lcm/ns/tests/__init__.py index 6a93c121..5541c3b7 100644 --- a/lcm/ns/tests/__init__.py +++ b/lcm/ns/tests/__init__.py @@ -47,3 +47,4 @@ SUBSCRIPTION_NS_OPERATION_DICT = fileutil.read_json_file(cur_path + '/data/subsc SUBSCRIPTION_NS_DELETION_DICT = fileutil.read_json_file(cur_path + '/data/subscription_ns_deletion.json') UPDATE_NS_DICT = fileutil.read_json_file(cur_path + '/data/update_ns.json') TERMINATE_NS_DICT = fileutil.read_json_file(cur_path + '/data/terminate_ns.json') +NSD_MODEL_DICT_INST_NS_POST_DEAL_VIEW = fileutil.read_json_file(cur_path + '/data/nsd_mode_inst_ns_post_deal_view.json') diff --git a/lcm/ns/tests/data/nsd_mode_inst_ns_post_deal_view.json b/lcm/ns/tests/data/nsd_mode_inst_ns_post_deal_view.json new file mode 100644 index 00000000..250e6ee0 --- /dev/null +++ b/lcm/ns/tests/data/nsd_mode_inst_ns_post_deal_view.json @@ -0,0 +1,7 @@ +{ + "policies": [{ + "properties": [{ + "drl_file_url": "drl_file_url" + }] + }] +} diff --git a/lcm/ns/tests/test_inst_ns_post_deal_view.py b/lcm/ns/tests/test_inst_ns_post_deal_view.py new file mode 100644 index 00000000..4bf97853 --- /dev/null +++ b/lcm/ns/tests/test_inst_ns_post_deal_view.py @@ -0,0 +1,53 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 json +import mock + +from django.test import TestCase +from lcm.pub.database.models import NSInstModel, ServiceBaseInfoModel +from lcm.pub.utils import restcall +from rest_framework import status +from rest_framework.test import APIClient +from lcm.ns.tests import NSD_MODEL_DICT_INST_NS_POST_DEAL_VIEW + + +class NSInstPostDealView(TestCase): + def setUp(self): + self.client = APIClient() + self.url = "/api/nslcm/v1/ns/test_ns_instance_id/postdeal" + self.data = {"status": "true"} + NSInstModel(id="test_ns_instance_id", name="test_ns_instance_name", nsd_id="test_nsd_id", + nsd_invariant_id="test_nsd_invariant_id", + nsd_model=json.dumps(NSD_MODEL_DICT_INST_NS_POST_DEAL_VIEW)).save() + ServiceBaseInfoModel(service_id="test_ns_instance_id", service_name="service_name", service_type="service_type", + active_status="active_status", status="status", creator="creator", create_time="0").save() + + def tearDown(self): + NSInstModel.objects.all().delete() + + @mock.patch.object(restcall, 'call_req') + def test_inst_ns_post_deal_view(self, mock_call_req): + ret = {"status": 1} + mock_vals = { + "api/polengine/v1/policyinfo": + [0, json.JSONEncoder().encode(ret), "200"], + } + + def side_effect(*args): + return mock_vals[args[4]] + + mock_call_req.side_effect = side_effect + + response = self.client.post(self.url, data=self.data, format='json') + self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code) diff --git a/lcm/ns/tests/test_ns_instant.py b/lcm/ns/tests/test_ns_instant.py index 7dd1f997..50a7508b 100644 --- a/lcm/ns/tests/test_ns_instant.py +++ b/lcm/ns/tests/test_ns_instant.py @@ -20,7 +20,7 @@ from rest_framework import status from rest_framework.test import APIClient from lcm.ns.biz.ns_instant import BuildInWorkflowThread from lcm.ns.biz.ns_instant import InstantNSService -from lcm.pub.database.models import NSInstModel +from lcm.pub.database.models import NSInstModel, WFPlanModel from lcm.pub.utils import restcall from lcm.pub.config import config from lcm.ns.tests import NSD_MODEL_DICT, NSD_MODEL_WITH_PNF_DICT, VNFM_LIST_IN_AAI_DICT, VNFM_IN_AAI_DICT, JOB_DICT, INSTANTIATE_NS_DICT, INSTANTIATE_NS_WITH_PNF_DICT @@ -38,7 +38,8 @@ class TestNsInstant(TestCase): self._mock_get_auto_id() def tearDown(self): - pass + NSInstModel.objects.all().delete() + WFPlanModel.objects.all().delete() def _mock_get_auto_id(self): fake_auto_id = mock.Mock() @@ -89,6 +90,56 @@ class TestNsInstant(TestCase): ack = InstantNSService(1, INSTANTIATE_NS_WITH_PNF_DICT).do_biz() self.assertEqual(ack['status'], status.HTTP_200_OK) + @mock.patch('lcm.ns.biz.ns_instantiate_flow.post_deal') + @mock.patch.object(restcall, 'call_req') + @mock.patch('lcm.ns.biz.ns_instantiate_flow.update_job') + @mock.patch('lcm.pub.msapi.sdc_run_catalog.parse_nsd', MagicMock(return_value=json.dumps(NSD_MODEL_WITH_PNF_DICT))) + @mock.patch('lcm.pub.msapi.extsys.select_vnfm', MagicMock(return_value=vnfminfo)) + def test_ns_instantiate_with_pnf_when_wso2(self, mock_updata_job, mock_call_req, mock_post_deal): + config.WORKFLOW_OPTION = "wso2" + NSInstModel(id="1", name="test_ns", nspackage_id="1", status="created", nsd_id="nsd_id").save() + stpls = [{"id": "nsd_id", "csarId": "csar_id", "templateName": "template_name", + "serviceTemplateId": "service_template_id"}] + items = [{"name": ["init"], "processId": "process_id"}] + ret = {"status": 1} + mock_vals = { + "/api/catalog/v1/servicetemplates": + [0, json.JSONEncoder().encode(stpls), "200"], + "/api/catalog/v1/servicetemplates/service_template_id/operations": + [0, json.JSONEncoder().encode(items), "200"], + "/api/wso2bpel/v1/process/instance": + [0, json.JSONEncoder().encode(ret), "200"], + } + + def side_effect(*args): + return mock_vals[args[4]] + + mock_call_req.side_effect = side_effect + ack = InstantNSService(1, INSTANTIATE_NS_WITH_PNF_DICT).do_biz() + self.assertEqual(ack['status'], status.HTTP_200_OK) + + @mock.patch('lcm.ns.biz.ns_instantiate_flow.post_deal') + @mock.patch.object(restcall, 'call_req') + @mock.patch('lcm.ns.biz.ns_instantiate_flow.update_job') + @mock.patch('lcm.pub.msapi.sdc_run_catalog.parse_nsd', MagicMock(return_value=json.dumps(NSD_MODEL_WITH_PNF_DICT))) + @mock.patch('lcm.pub.msapi.extsys.select_vnfm', MagicMock(return_value=vnfminfo)) + def test_ns_instantiate_with_pnf_when_activiti(self, mock_updata_job, mock_call_req, mock_post_deal): + config.WORKFLOW_OPTION = "activiti" + NSInstModel(id="1", name="test_ns", nspackage_id="1", status="created", nsd_id="nsd_id").save() + WFPlanModel(deployed_id="1", process_id="process_id", message="message", status=1, plan_name="plan_name").save() + ret = {"status": 1} + mock_vals = { + "api/workflow/v1/process/instance": + [0, json.JSONEncoder().encode(ret), "200"], + } + + def side_effect(*args): + return mock_vals[args[4]] + + mock_call_req.side_effect = side_effect + ack = InstantNSService(1, INSTANTIATE_NS_WITH_PNF_DICT).do_biz() + self.assertEqual(ack['status'], status.HTTP_200_OK) + @mock.patch.object(restcall, 'call_req') @mock.patch('lcm.pub.msapi.sdc_run_catalog.parse_nsd', MagicMock(return_value=json.dumps(NSD_MODEL_WITH_PNF_DICT))) @mock.patch('lcm.pub.msapi.extsys.select_vnfm', MagicMock(return_value=vnfminfo)) diff --git a/lcm/ns/tests/test_sol_update_ns_api.py b/lcm/ns/tests/test_sol_update_ns_api.py new file mode 100644 index 00000000..302aed5d --- /dev/null +++ b/lcm/ns/tests/test_sol_update_ns_api.py @@ -0,0 +1,42 @@ +# Copyright 2019 ZTE Corporation. +# +# 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 json + +import mock +from django.test import TestCase +from rest_framework import status +from rest_framework.test import APIClient +from lcm.pub.database.models import NSInstModel +from lcm.ns.biz.ns_update import NSUpdateService +from lcm.ns.tests import NSD_MODEL_DICT + + +class TestUpdateNSApi(TestCase): + + def setUp(self): + self.apiClient = APIClient() + self.format = "json" + self.url = "/api/nslcm/v1/ns_instances/test_update_ns/update" + self.data = {"updateType": "ADD_VNF"} + NSInstModel(id="test_update_ns", name="test_ns_instance_name", nsd_id="test_nsd_id", + nsd_invariant_id="test_nsd_invariant_id", nsd_model=json.dumps(NSD_MODEL_DICT)).save() + + def tearDown(self): + NSInstModel.objects.all().delete() + + @mock.patch.object(NSUpdateService, 'run') + def test_create_ns(self, mock_run): + response = self.client.post(self.url, data=self.data, format='json') + self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code) diff --git a/lcm/ns_vnfs/biz/create_vnfs.py b/lcm/ns_vnfs/biz/create_vnfs.py index a901f15c..cb645322 100644 --- a/lcm/ns_vnfs/biz/create_vnfs.py +++ b/lcm/ns_vnfs/biz/create_vnfs.py @@ -400,6 +400,8 @@ class CreateVnfs(Thread): } try: SubscriptionCreation(data).do_biz() + except NSLCMException as e: + logger.error("subscribe failed: %s", e.args[0]) except Exception as e: logger.error("subscribe failed: %s", e.args[0]) diff --git a/lcm/ns_vnfs/biz/subscribe.py b/lcm/ns_vnfs/biz/subscribe.py index b9e916fb..2de67ca7 100644 --- a/lcm/ns_vnfs/biz/subscribe.py +++ b/lcm/ns_vnfs/biz/subscribe.py @@ -130,7 +130,7 @@ class SubscriptionDeletion(object): def send_subscription_deletion_request(self): if self.subscription: - self.subscription_id = ignore_case_get(self.subscription, 'id') + self.subscription_id = ignore_case_get(self.subscription.__dict__, 'id') ret = req_by_msb('api/gvnfmdriver/v1/%s/subscriptions/%s' % (self.vnfm_id, self.subscription_id), 'DELETE') if ret[0] != 0: logger.error('Status code is %s, detail is %s.', ret[2], ret[1]) diff --git a/lcm/ns_vnfs/biz/terminate_nfs.py b/lcm/ns_vnfs/biz/terminate_nfs.py index 8f9f5ecf..1dec71d2 100644 --- a/lcm/ns_vnfs/biz/terminate_nfs.py +++ b/lcm/ns_vnfs/biz/terminate_nfs.py @@ -92,6 +92,7 @@ class TerminateVnfs(threading.Thread): vnf_inst_info = self.get_vnf_inst() if not vnf_inst_info: self.add_progress(100, "TERM_VNF_NOT_EXIST_SUCCESS", "finished") + return None self.add_progress(2, "GET_VNF_INST_SUCCESS") self.vnfm_inst_id = vnf_inst_info.vnfm_inst_id self.vnf_uuid = vnf_inst_info.mnfinstid diff --git a/lcm/ns_vnfs/tests/tests.py b/lcm/ns_vnfs/tests/tests.py index b4c60cfc..b4904329 100644 --- a/lcm/ns_vnfs/tests/tests.py +++ b/lcm/ns_vnfs/tests/tests.py @@ -20,7 +20,7 @@ from django.test import TestCase, Client from rest_framework import status from lcm.pub.database.models import VLInstModel, NfInstModel, JobModel, NSInstModel, VmInstModel, \ - OOFDataModel, VNFCInstModel, PortInstModel, CPInstModel + OOFDataModel, VNFCInstModel, PortInstModel, CPInstModel, SubscriptionModel from lcm.pub.exceptions import NSLCMException from lcm.pub.utils import restcall from lcm.jobs.enum import JOB_MODEL_STATUS, JOB_TYPE, JOB_ACTION, JOB_PROGRESS @@ -93,10 +93,13 @@ class TestTerminateVnfViews(TestCase): vimid='{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}', instid=self.nf_inst_id ) + SubscriptionModel(vnf_instance_filter=self.nf_inst_id, callback_uri="", links="").save() def tearDown(self): NSInstModel.objects.all().delete() NfInstModel.objects.all().delete() + VmInstModel.objects.all().delete() + SubscriptionModel.objects.all().delete() @mock.patch.object(TerminateVnfs, "run") def test_terminate_vnf_url(self, mock_run): @@ -109,8 +112,7 @@ class TestTerminateVnfViews(TestCase): @mock.patch.object(time, "sleep") @mock.patch.object(restcall, "call_req") - @mock.patch.object(SubscriptionDeletion, "send_subscription_deletion_request") - def test_terminate_vnf(self, mock_send_subscription_deletion_request, mock_call_req, mock_sleep): + def test_terminate_vnf(self, mock_call_req, mock_sleep): job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, self.nf_inst_id) job_info = { "jobId": job_id, @@ -124,7 +126,9 @@ class TestTerminateVnfViews(TestCase): "/api/ztevnfmdriver/v1/1/jobs/" + job_id + "?responseId=0": [0, json.JSONEncoder().encode(job_info), "200"], "/api/resmgr/v1/vnf/1": - [0, json.JSONEncoder().encode({"jobId": job_id}), "200"] + [0, json.JSONEncoder().encode({"jobId": job_id}), "200"], + "api/gvnfmdriver/v1/1/subscriptions/": + [0, json.JSONEncoder().encode({}), "200"] } def side_effect(*args): @@ -138,6 +142,62 @@ class TestTerminateVnfViews(TestCase): self.assertEqual(1, 1) self.assertEqual(JobModel.objects.get(jobid=job_id).progress, 100) + @mock.patch.object(time, "sleep") + @mock.patch.object(restcall, "call_req") + @mock.patch.object(SubscriptionDeletion, "send_subscription_deletion_request") + def test_terminate_vnf_when_no_vnf_uuid(self, mock_send_subscription_deletion_request, mock_call_req, mock_sleep): + nf_inst_id = "test_terminate_vnf_when_no_vnf_uuid" + NSInstModel(id=nf_inst_id, name="ns_name_2").save() + NfInstModel.objects.create(nfinstid=nf_inst_id, + vnfm_inst_id="2", + status="active", + vnfd_model=self.vnfd_model + ) + VmInstModel.objects.create(vmid="2", + vimid='{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}', + instid=nf_inst_id + ) + job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, nf_inst_id) + job_info = { + "jobId": job_id, + "responsedescriptor": {"status": JOB_MODEL_STATUS.FINISHED} + } + mock_vals = { + "/external-system/esr-vnfm-list/esr-vnfm/2?depth=all": + [0, json.JSONEncoder().encode(vnfm_info), "200"], + "/api/ztevnfmdriver/v1/2/vnfs/None/terminate": + [0, json.JSONEncoder().encode({"jobId": job_id}), "200"], + "/api/ztevnfmdriver/v1/2/jobs/" + job_id + "?responseId=0": + [0, json.JSONEncoder().encode(job_info), "200"], + "/api/resmgr/v1/vnf/%s" % nf_inst_id: + [0, json.JSONEncoder().encode({"jobId": job_id}), "200"] + } + + def side_effect(*args): + return mock_vals[args[4]] + + mock_call_req.side_effect = side_effect + TerminateVnfs(self.data, nf_inst_id, job_id).run() + nfinst = NfInstModel.objects.filter(nfinstid=nf_inst_id) + if nfinst: + self.assertEqual(1, 0) + else: + self.assertEqual(1, 1) + self.assertEqual(JobModel.objects.get(jobid=job_id).progress, 100) + + @mock.patch.object(time, "sleep") + @mock.patch.object(restcall, "call_req") + @mock.patch.object(SubscriptionDeletion, "send_subscription_deletion_request") + def test_terminate_vnf_when_nf_not_exists(self, mock_send_subscription_deletion_request, mock_call_req, mock_sleep): + job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, self.nf_inst_id) + TerminateVnfs(self.data, "nf_not_exists", job_id).run() + nfinst = NfInstModel.objects.filter(nfinstid="nf_not_exists") + if nfinst: + self.assertEqual(1, 0) + else: + self.assertEqual(1, 1) + self.assertEqual(JobModel.objects.get(jobid=job_id).progress, 255) + def test_terminate_vnf_when_vnf_is_dealing(self): NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.TERMINATING) job_id = JobUtil.create_job(JOB_TYPE.VNF, JOB_ACTION.TERMINATE, self.nf_inst_id) @@ -553,6 +613,8 @@ class TestPlaceVnfViews(TestCase): self.vnf_inst_id = "1234" self.vnf_id = "vG" self.client = Client() + self.url = "/api/nslcm/v1/ns/placevnf" + self.data = vnf_place_request OOFDataModel.objects.all().delete() OOFDataModel.objects.create( request_id="1234", @@ -577,6 +639,7 @@ class TestPlaceVnfViews(TestCase): "flavorId": "12345", "directive": [] }] + # response = self.client.post(self.url, data=self.data) PlaceVnfs(vnf_place_request).extract() db_info = OOFDataModel.objects.filter(request_id=vnf_place_request.get("requestId"), transaction_id=vnf_place_request.get("transactionId")) self.assertEqual(db_info[0].request_status, "completed") @@ -1150,7 +1213,7 @@ class TestCreateVnfViews(TestCase): "statusdescription": "creating", "errorcode": "0"}]}}), "200"], "api/gvnfmdriver/v1/1/subscriptions": - [0, json.JSONEncoder().encode({}), "200"], + [0, json.JSONEncoder().encode(subscription_response_data), "200"], "/api/resmgr/v1/vnfinfo": [0, json.JSONEncoder().encode(subscription_response_data), "200"], @@ -1292,6 +1355,55 @@ class TestCreateVnfViews(TestCase): ret = OOFDataModel.objects.filter(request_id="1234", transaction_id="1234") self.assertIsNotNone(ret) + @mock.patch.object(time, "sleep") + @mock.patch.object(restcall, "call_req") + def test_create_vnf_thread_sucess_when_failed_to_subscribe_from_vnfm(self, mock_call_req, mock_sleep): + mock_sleep.return_value = None + nf_inst_id, job_id = create_vnfs.prepare_create_params() + mock_vals = { + "/api/catalog/v1/vnfpackages/zte_vbras": + [0, json.JSONEncoder().encode(nf_package_info), "200"], + "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all": + [0, json.JSONEncoder().encode(vnfm_info), "200"], + "/api/ztevnfmdriver/v1/1/vnfs": + [0, json.JSONEncoder().encode({"jobId": self.job_id, "vnfInstanceId": 3}), "200"], + "/api/oof/v1/placement": + [0, json.JSONEncoder().encode({}), "202"], + "/api/resmgr/v1/vnf": + [0, json.JSONEncoder().encode({}), "200"], + "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0": + [0, json.JSONEncoder().encode({"jobid": self.job_id, + "responsedescriptor": {"progress": "100", + "status": JOB_MODEL_STATUS.FINISHED, + "responseid": "3", + "statusdescription": "creating", + "errorcode": "0", + "responsehistorylist": [ + {"progress": "0", + "status": JOB_MODEL_STATUS.PROCESSING, + "responseid": "2", + "statusdescription": "creating", + "errorcode": "0"}]}}), "200"], + "api/gvnfmdriver/v1/1/subscriptions": + [1, json.JSONEncoder().encode(subscription_response_data), "200"], + "/api/resmgr/v1/vnfinfo": + [0, json.JSONEncoder().encode(subscription_response_data), "200"], + } + + def side_effect(*args): + return mock_vals[args[4]] + + mock_call_req.side_effect = side_effect + data = { + "ns_instance_id": ignore_case_get(self.data, "nsInstanceId"), + "additional_param_for_ns": ignore_case_get(self.data, "additionalParamForNs"), + "additional_param_for_vnf": ignore_case_get(self.data, "additionalParamForVnf"), + "vnf_index": ignore_case_get(self.data, "vnfIndex") + } + CreateVnfs(data, nf_inst_id, job_id).run() + self.assertEqual(NfInstModel.objects.get(nfinstid=nf_inst_id).status, VNF_STATUS.ACTIVE) + self.assertEqual(JobModel.objects.get(jobid=job_id).progress, JOB_PROGRESS.FINISHED) + class TestUpdateVnfsViews(TestCase): def setUp(self): @@ -2182,6 +2294,7 @@ class TestVnfNotifyView(TestCase): CPInstModel.objects.all().delete() def test_handle_vnf_lcm_ooc_notification_when_change_type_is_added(self): + # response = self.client.post(self.url, data=self.data) HandleVnfLcmOocNotification(self.vnfm_inst_id, self.m_nf_inst_id, self.data).do_biz() vnfc_inst = VNFCInstModel.objects.get(vnfcinstanceid="vnfc_instance_id", vduid="vdu_id", nfinstid=self.nf_inst_id, vmid="resource_id")