From 0f3aeb52bb79baef084a2e8d5469acc0e5819c3c Mon Sep 17 00:00:00 2001 From: erlei Date: Thu, 25 Jul 2019 17:33:15 +0800 Subject: ADD UT for ns_lcm Issue-ID: VFC-1429 Signed-off-by: zhuerlei Issue-ID: VFC-1429 Change-Id: I0bb67ab89b15ef5f69809d7055082c13551d53cc Signed-off-by: erlei --- lcm/jobs/tests/tests.py | 5 + lcm/ns/data/scalemapping.json | 134 +++++++++++++++++ lcm/ns/tests/__init__.py | 3 + lcm/ns/tests/data/scale_ns_thread.json | 12 ++ lcm/ns/tests/data/scalemapping.json | 40 +++-- lcm/ns/tests/data/terminate_ns.json | 2 + lcm/ns/tests/data/update_ns.json | 9 ++ lcm/ns/tests/test_ns_heal.py | 236 ++++++++++++++++++++++------- lcm/ns/tests/test_ns_manual_scale.py | 226 ++++++++++++++++------------ lcm/ns/tests/test_ns_terminate.py | 146 ++++++++++++++++++ lcm/ns/tests/test_ns_update.py | 129 ++++++++++++++++ lcm/ns/tests/test_scaleaspect.py | 265 ++++++++++++--------------------- 12 files changed, 870 insertions(+), 337 deletions(-) create mode 100644 lcm/ns/data/scalemapping.json create mode 100644 lcm/ns/tests/data/scale_ns_thread.json create mode 100644 lcm/ns/tests/data/terminate_ns.json create mode 100644 lcm/ns/tests/data/update_ns.json create mode 100644 lcm/ns/tests/test_ns_terminate.py create mode 100644 lcm/ns/tests/test_ns_update.py diff --git a/lcm/jobs/tests/tests.py b/lcm/jobs/tests/tests.py index 7a1ef1ab..736dad2f 100644 --- a/lcm/jobs/tests/tests.py +++ b/lcm/jobs/tests/tests.py @@ -56,6 +56,11 @@ class JobsViewTest(TestCase): self.assertIn('jobId', response.data) self.assertNotIn('responseDescriptor', response.data) + def test_query_ns_job_with_error_response_id(self): + url = JOB_INSTANCE_URI % self.job_id + "?responseId='zzz'" + response = self.client.get(url) + self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code) + def test_query_job_with_response_id(self): JobModel(jobid=self.job_id, jobtype=JOB_TYPE.NS, diff --git a/lcm/ns/data/scalemapping.json b/lcm/ns/data/scalemapping.json new file mode 100644 index 00000000..74351017 --- /dev/null +++ b/lcm/ns/data/scalemapping.json @@ -0,0 +1,134 @@ +{ + "scale_options": [ + { + "nsd_id": "01", + "ns_instanceId": "ns_instanceId_01", + "ns_scale_aspect": "TIC_EDGE_IMS", + "ns_scale_info_list": [ + { + "step": 1, + "vnf_scale_info": [ + { + "vnfInstanceId": "nf_zte_cscf", + "vnf_scaleAspectId": "gsu", + "numberOfSteps": "1" + }, + { + "vnfInstanceId": "nf_zte_hss", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "3" + } + ] + }, + { + "step": 2, + "vnf_scale_info": [ + { + "vnfInstanceId": "nf_zte_cscf", + "vnf_scaleAspectId": "mpu", + "numberOfSteps": "2" + }, + { + "vnfInstanceId": "nf_zte_hss", + "vnf_scaleAspectId": "mpu", + "numberOfSteps": "4" + } + ] + } + ] + }, + { + "nsd_id": "02", + "ns_scale_aspect": "TIC_EDGE_HW", + "ns_scale_info": [ + { + "step": 4, + "vnf_scale_info": [ + { + "vnfd_id": "nf_hw_cscf", + "vnf_scaleAspectId": "gsu", + "numberOfSteps": "1" + }, + { + "vnfd_id": "nf_hw_hss", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "1" + } + ] + }, + { + "step": 6, + "vnf_scale_info": [ + { + "vnfd_id": "nf_HW_cscf", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "1" + }, + { + "vnfd_id": "nf_HW_hss", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "1" + } + ] + } + ] + }, + { + "nsd_id": "03", + "ns_scale_aspect": "TIC_EDGE_HW", + "ns_scale_info_list": [ + { + "step": "4", + "vnf_scale_info": [ + { + "vnfd_id": "nf_hw_cscf", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "123" + }, + { + "vnfd_id": "nf_hw_hss", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "456" + } + ] + }, + { + "step": 6, + "vnf_scale_info": [ + { + "vnfd_id": "nf_HW_cscf", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "1" + }, + { + "vnfd_id": "nf_HW_hss", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "1" + } + ] + } + ] + }, + { + "nsd_id": "test_ns_manual_scale", + "ns_scale_aspect": "test_ns_manual_scale_aspectId", + "ns_scale_info": [ + { + "step": 1, + "vnf_scale_info": [ + { + "vnfd_id": "nf_001", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "123" + }, + { + "vnfd_id": "nf_002", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "456" + } + ] + } + ] + } + ] +} diff --git a/lcm/ns/tests/__init__.py b/lcm/ns/tests/__init__.py index bf1956af..6a93c121 100644 --- a/lcm/ns/tests/__init__.py +++ b/lcm/ns/tests/__init__.py @@ -32,6 +32,7 @@ INSTANTIATE_NS_DICT = fileutil.read_json_file(cur_path + '/data/instantiate_ns.j SCALE_DICT = fileutil.read_json_file(cur_path + '/data/scale.json') SCALING_MAP_DICT = fileutil.read_json_file(cur_path + '/data/scalemapping.json') SCALE_NS_DICT = fileutil.read_json_file(cur_path + '/data/scale_ns.json') +SCALE_NS_THREAD_DICT = fileutil.read_json_file(cur_path + '/data/scale_ns_thread.json') OCCURRENCE_DICT = fileutil.read_json_file(cur_path + '/data/occurrence.json') NSLCMOP_WITH_EXCLUDE_DEFAULT_DICT = fileutil.read_json_file(cur_path + '/data/occurrence_exclude_default.json') SUBSCRIPTION_DICT = fileutil.read_json_file(cur_path + '/data/subscription.json') @@ -44,3 +45,5 @@ SOL_INSTANTIATE_NS_WITH_PNF_DICT = fileutil.read_json_file(cur_path + '/data/sol VCPE_NS_MODEL_DICT = fileutil.read_json_file(cur_path + '/data/vcpe_ns_model.json') SUBSCRIPTION_NS_OPERATION_DICT = fileutil.read_json_file(cur_path + '/data/subscription_ns_operation.json') 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') diff --git a/lcm/ns/tests/data/scale_ns_thread.json b/lcm/ns/tests/data/scale_ns_thread.json new file mode 100644 index 00000000..27a66ddf --- /dev/null +++ b/lcm/ns/tests/data/scale_ns_thread.json @@ -0,0 +1,12 @@ +{ + "scaleType": "SCALE_NS", + "scaleNsData": + { + "scaleNsByStepsData": { + "aspectId": "test_ns_manual_scale_aspectId", + "numberOfSteps": 1, + "scalingDirection": "0" + } + } + +} diff --git a/lcm/ns/tests/data/scalemapping.json b/lcm/ns/tests/data/scalemapping.json index 2468e9b0..74351017 100644 --- a/lcm/ns/tests/data/scalemapping.json +++ b/lcm/ns/tests/data/scalemapping.json @@ -1,19 +1,20 @@ { "scale_options": [ { - "nsd_id": "23", + "nsd_id": "01", + "ns_instanceId": "ns_instanceId_01", "ns_scale_aspect": "TIC_EDGE_IMS", - "ns_scale_info": [ + "ns_scale_info_list": [ { "step": 1, "vnf_scale_info": [ { - "vnfd_id": "nf_zte_cscf", + "vnfInstanceId": "nf_zte_cscf", "vnf_scaleAspectId": "gsu", "numberOfSteps": "1" }, { - "vnfd_id": "nf_zte_hss", + "vnfInstanceId": "nf_zte_hss", "vnf_scaleAspectId": "gpu", "numberOfSteps": "3" } @@ -23,12 +24,12 @@ "step": 2, "vnf_scale_info": [ { - "vnfd_id": "nf_zte_cscf", + "vnfInstanceId": "nf_zte_cscf", "vnf_scaleAspectId": "mpu", "numberOfSteps": "2" }, { - "vnfd_id": "nf_zte_hss", + "vnfInstanceId": "nf_zte_hss", "vnf_scaleAspectId": "mpu", "numberOfSteps": "4" } @@ -37,7 +38,7 @@ ] }, { - "nsd_id": "23", + "nsd_id": "02", "ns_scale_aspect": "TIC_EDGE_HW", "ns_scale_info": [ { @@ -73,9 +74,9 @@ ] }, { - "nsd_id": 235, + "nsd_id": "03", "ns_scale_aspect": "TIC_EDGE_HW", - "ns_scale_info": [ + "ns_scale_info_list": [ { "step": "4", "vnf_scale_info": [ @@ -107,6 +108,27 @@ ] } ] + }, + { + "nsd_id": "test_ns_manual_scale", + "ns_scale_aspect": "test_ns_manual_scale_aspectId", + "ns_scale_info": [ + { + "step": 1, + "vnf_scale_info": [ + { + "vnfd_id": "nf_001", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "123" + }, + { + "vnfd_id": "nf_002", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "456" + } + ] + } + ] } ] } diff --git a/lcm/ns/tests/data/terminate_ns.json b/lcm/ns/tests/data/terminate_ns.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lcm/ns/tests/data/terminate_ns.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lcm/ns/tests/data/update_ns.json b/lcm/ns/tests/data/update_ns.json new file mode 100644 index 00000000..24a08c74 --- /dev/null +++ b/lcm/ns/tests/data/update_ns.json @@ -0,0 +1,9 @@ +{ + "updateType": "OPERATE_VNF", + "OperateVnfData": [{ + "vnfInstanceId": "test_vnf_001", + "changeStateTo": {"OperationalStates": "STOPPED"}, + "stopType": "GRACEFUL", + "gracefulStopTimeout": "2019-01-01" + }] +} diff --git a/lcm/ns/tests/test_ns_heal.py b/lcm/ns/tests/test_ns_heal.py index c6bf8a3a..14675031 100644 --- a/lcm/ns/tests/test_ns_heal.py +++ b/lcm/ns/tests/test_ns_heal.py @@ -1,29 +1,31 @@ # Copyright 2017 Intel Corporation. # -# Licensed under the Apache License, Version 2.0 (the "License"); +# 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, +# 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 mock +import time from django.test import TestCase -import mock from rest_framework.test import APIClient from rest_framework import status + +from lcm.jobs.enum import JOB_TYPE, JOB_ACTION, JOB_PROGRESS from lcm.ns.biz.ns_heal import NSHealService from lcm.ns.enum import NS_INST_STATUS -from lcm.pub.database.models import NSInstModel, NfInstModel -from lcm.pub.exceptions import NSLCMException -from lcm.pub.utils.jobutil import JobUtil -from lcm.jobs.enum import JOB_TYPE, JOB_ACTION from lcm.ns_vnfs.biz.heal_vnfs import NFHealService from lcm.ns.tests import HEAL_NS_DICT, HEAL_VNF_DICT, VNFD_MODEL_DICT +from lcm.pub.database.models import NSInstModel, NfInstModel, JobModel, VNFCInstModel, VmInstModel, NSLcmOpOccModel +from lcm.pub.exceptions import NSLCMException +from lcm.pub.utils.jobutil import JobUtil class TestHealNsViews(TestCase): @@ -35,7 +37,7 @@ class TestHealNsViews(TestCase): self.client = APIClient() NSInstModel.objects.filter().delete() NfInstModel.objects.filter().delete() - NSInstModel(id=self.ns_inst_id, name="ns_name", status='null').save() + NSInstModel(id=self.ns_inst_id, name='ns_name', status='null').save() NfInstModel.objects.create(nfinstid=self.nf_inst_id, nf_name='name_1', vnf_id='1', @@ -44,86 +46,206 @@ class TestHealNsViews(TestCase): max_cpu='14', max_ram='12296', max_hd='101', - max_shd="20", + max_shd='20', max_net=10, status='null', mnfinstid=self.nf_uuid, package_id='pkg1', vnfd_model=VNFD_MODEL_DICT) + VNFCInstModel(nfinstid=self.nf_inst_id, vmid='vmid_01', vduid='vduid_01').save() + VmInstModel(vmid='vmid_01', vmname='vmname_01').save() def tearDown(self): - pass + NSInstModel.objects.all().delete() + NfInstModel.objects.all().delete() + VNFCInstModel.objects.all().delete() + VmInstModel.objects.all().delete() @mock.patch.object(NSHealService, 'run') def test_heal_vnf_url(self, mock_run): heal_vnf_json = HEAL_VNF_DICT.copy() - heal_vnf_json["healVnfData"]["vnfInstanceId"] = self.nf_inst_id - response = self.client.post("/api/nslcm/v1/ns/%s/heal" % self.ns_inst_id, data=heal_vnf_json, format='json') + heal_vnf_json['healVnfData']['vnfInstanceId'] = self.nf_inst_id + response = self.client.post('/api/nslcm/v1/ns/%s/heal' % self.ns_inst_id, data=heal_vnf_json, format='json') self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code, response.data) self.assertIsNotNone(response.data) - self.assertIn("jobId", response.data) - self.assertNotIn("error", response.data) - response = self.client.delete("/api/nslcm/v1/ns/%s" % self.ns_inst_id) + self.assertIn('jobId', response.data) + self.assertNotIn('error', response.data) + response = self.client.delete('/api/nslcm/v1/ns/%s' % self.ns_inst_id) self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code) # add healNsData @mock.patch.object(NSHealService, 'run') def test_heal_ns_url(self, mock_run): heal_ns_json = HEAL_NS_DICT.copy() - heal_ns_json["healNsData"]["vnfInstanceId"] = self.nf_inst_id - response = self.client.post("/api/nslcm/v1/ns/%s/heal" % self.ns_inst_id, data=heal_ns_json, format='json') + heal_ns_json['healNsData']['vnfInstanceId'] = self.nf_inst_id + response = self.client.post('/api/nslcm/v1/ns/%s/heal' % self.ns_inst_id, data=heal_ns_json, format='json') self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code, response.data) self.assertIsNotNone(response.data) - self.assertIn("jobId", response.data) - self.assertNotIn("error", response.data) - response = self.client.delete("/api/nslcm/v1/ns/%s" % self.ns_inst_id) + self.assertIn('jobId', response.data) + self.assertNotIn('error', response.data) + response = self.client.delete('/api/nslcm/v1/ns/%s' % self.ns_inst_id) self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code) - @mock.patch.object(NFHealService, 'start') - @mock.patch.object(NSHealService, 'wait_job_finish') - @mock.patch.object(NSHealService, 'update_job') - def test_heal_vnf_thread(self, mock_start, mock_wait, mock_update): - heal_vnf_json = HEAL_VNF_DICT.copy() - heal_vnf_json["healVnfData"]["vnfInstanceId"] = self.nf_inst_id - NSHealService(self.ns_inst_id, heal_vnf_json, self.job_id).run() - self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.HEALING) - - # add healNsData - @mock.patch.object(NFHealService, 'start') - @mock.patch.object(NSHealService, 'wait_job_finish') - @mock.patch.object(NSHealService, 'update_job') - def test_heal_ns_thread(self, mock_start, mock_wait, mock_update): - heal_ns_json = HEAL_NS_DICT.copy() - heal_ns_json["healNsData"]["vnfInstanceId"] = self.nf_inst_id - NSHealService(self.ns_inst_id, heal_ns_json, self.job_id).run() - self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.HEALING) - - @mock.patch.object(NSHealService, "start") + @mock.patch.object(NSHealService, 'start') def test_heal_vnf_non_existing_ns(self, mock_start): - mock_start.side_effect = NSLCMException("NS Not Found") - ns_inst_id = "2" + mock_start.side_effect = NSLCMException('NS Not Found') + ns_inst_id = '2' heal_vnf_json = HEAL_VNF_DICT.copy() - heal_vnf_json["healVnfData"]["vnfInstanceId"] = self.nf_inst_id - response = self.client.post("/api/nslcm/v1/ns/%s/heal" % ns_inst_id, data=heal_vnf_json, format='json') - self.assertEqual(response.data["error"], "NS Not Found") + heal_vnf_json['healVnfData']['vnfInstanceId'] = self.nf_inst_id + response = self.client.post('/api/nslcm/v1/ns/%s/heal' % ns_inst_id, data=heal_vnf_json, format='json') + self.assertEqual(response.data['error'], 'NS Not Found') self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertIn("error", response.data) + self.assertIn('error', response.data) # add healNsData - @mock.patch.object(NSHealService, "start") + @mock.patch.object(NSHealService, 'start') def test_heal_ns_heal_non_existing_ns(self, mock_start): - mock_start.side_effect = NSLCMException("NS Not Found") - ns_inst_id = "2" + mock_start.side_effect = NSLCMException('NS Not Found') + ns_inst_id = '2' heal_ns_json = HEAL_NS_DICT.copy() - heal_ns_json["healNsData"]["vnfInstanceId"] = self.nf_inst_id - response = self.client.post("/api/nslcm/v1/ns/%s/heal" % ns_inst_id, data=heal_ns_json, format='json') - self.assertEqual(response.data["error"], "NS Not Found") + heal_ns_json['healNsData']['vnfInstanceId'] = self.nf_inst_id + response = self.client.post('/api/nslcm/v1/ns/%s/heal' % ns_inst_id, data=heal_ns_json, format='json') + self.assertEqual(response.data['error'], 'NS Not Found') self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertIn("error", response.data) + self.assertIn('error', response.data) - @mock.patch.object(NSHealService, "start") + @mock.patch.object(NSHealService, 'start') def test_heal_vnf_empty_post(self, mock_start): - mock_start.side_effect = NSLCMException("healVnfData parameter does not exist or value is incorrect.") - response = self.client.post("/api/nslcm/v1/ns/%s/heal" % self.ns_inst_id, data={}) + mock_start.side_effect = NSLCMException('healVnfData parameter does not exist or value is incorrect.') + response = self.client.post('/api/nslcm/v1/ns/%s/heal' % self.ns_inst_id, data={}) self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertIn("error", response.data) + self.assertIn('error', response.data) + + @mock.patch.object(NFHealService, 'run') + @mock.patch.object(time, 'sleep') + @mock.patch.object(JobModel.objects, 'get') + def test_heal_vnf_thread(self, mock_get, mock_sleep, mock_run): + mock_run.return_value = None + mock_sleep.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.FINISHED) + heal_vnf_json = HEAL_VNF_DICT.copy() + heal_vnf_json['healVnfData']['vnfInstanceId'] = self.nf_inst_id + NSHealService(self.ns_inst_id, heal_vnf_json, self.job_id).run() + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + + # add healNsData + @mock.patch.object(NFHealService, 'run') + @mock.patch.object(time, 'sleep') + @mock.patch.object(JobModel.objects, 'get') + def test_heal_ns_thread(self, mock_get, mock_sleep, mock_run): + mock_run.return_value = None + mock_sleep.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.FINISHED) + heal_ns_json = HEAL_NS_DICT.copy() + heal_ns_json['healNsData']['vnfInstanceId'] = self.nf_inst_id + NSHealService(self.ns_inst_id, heal_ns_json, self.job_id).run() + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + + def test_heal_when_ns_does_not_exist(self): + ns_inst_id = '2' + ns_heal_service = NSHealService(ns_inst_id, {}, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_when_healnsdata_and_healvnfdata_parameters_does_not_exist(self): + ns_heal_service = NSHealService(self.nf_inst_id, {}, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_when_healnsdata_and_healvnfdata_parameters_exist_together(self): + data = { + 'healNsData': {'degreeHealing': 'HEAL_RESTORE'}, + 'healVnfData': {'vnfInstanceId': 'default'} + } + ns_heal_service = NSHealService(self.nf_inst_id, data, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + @mock.patch.object(NFHealService, 'run') + @mock.patch.object(time, 'sleep') + @mock.patch.object(JobModel.objects, 'get') + def test_heal_vnf_thread_when_nf_heal_failed(self, mock_get, mock_sleep, mock_run): + mock_run.return_value = None + mock_sleep.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.ERROR) + heal_vnf_json = HEAL_VNF_DICT.copy() + heal_vnf_json['healVnfData']['vnfInstanceId'] = self.nf_inst_id + ns_heal_service = NSHealService(self.ns_inst_id, heal_vnf_json, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + @mock.patch.object(NFHealService, 'run') + @mock.patch.object(time, 'sleep') + @mock.patch.object(JobModel.objects, 'get') + def test_heal_ns_thread_when_nf_heal_failed(self, mock_get, mock_sleep, mock_run): + mock_run.return_value = None + mock_sleep.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.ERROR) + heal_ns_json = HEAL_NS_DICT.copy() + heal_ns_json['healNsData']['vnfInstanceId'] = self.nf_inst_id + ns_heal_service = NSHealService(self.ns_inst_id, heal_ns_json, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_vnf_thread_when_vnfinstanceid_does_not_exist(self): + heal_vnf_json = {'healVnfData': {'vnfInstanceId': ''}} + ns_heal_service = NSHealService(self.ns_inst_id, heal_vnf_json, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_ns_thread_when_degreeHealing_does_not_exist(self): + heal_ns_json = {'healNsData': {'degreeHealing': ''}} + ns_heal_service = NSHealService(self.ns_inst_id, heal_ns_json, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_ns_thread_when_the_degree_of_healing_does_not_exist(self): + heal_ns_json = {'healNsData': {'degreeHealing': 'xxx'}} + ns_heal_service = NSHealService(self.ns_inst_id, heal_ns_json, self.job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_ns_thread_when_nsinsts_does_not_exist(self): + NSInstModel(id='text_nsinsts_does_not_exist', name='ns_name', status='null').save() + heal_ns_json = HEAL_NS_DICT.copy() + heal_ns_json['healNsData']['vnfInstanceId'] = 'text_nsinsts_does_not_exist' + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.HEAL, 'text_nsinsts_does_not_exist') + ns_heal_service = NSHealService('text_nsinsts_does_not_exist', heal_ns_json, job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_ns_thread_when_vnfcinsts_does_not_exist(self): + NSInstModel(id='text_vnfcinsts_does_not_exist', name='ns_name', status='null').save() + NfInstModel.objects.create(nfinstid='text_vnfcinsts_does_not_exist_nf_id', + ns_inst_id='text_vnfcinsts_does_not_exist') + heal_ns_json = HEAL_NS_DICT.copy() + heal_ns_json['healNsData']['vnfInstanceId'] = 'text_vnfcinsts_does_not_exist_nf_id' + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.HEAL, 'text_vnfcinsts_does_not_exist') + ns_heal_service = NSHealService('text_vnfcinsts_does_not_exist', heal_ns_json, job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_heal_ns_thread_when_vminstinfo_does_not_exist(self): + ns_inst_id = 'text_vminstinfo_does_not_exist' + NSInstModel(id=ns_inst_id, name='ns_name', status='null').save() + NfInstModel.objects.create(nfinstid='text_vminstinfo_does_not_exist_nf_id', + ns_inst_id=ns_inst_id) + VNFCInstModel(nfinstid='text_vminstinfo_does_not_exist_nf_id', vmid='text_vminstinfo_does_not_exist_vm_id', + vduid='text_vminstinfo_does_not_exist_vdu_id').save() + heal_ns_json = HEAL_NS_DICT.copy() + heal_ns_json['healNsData']['vnfInstanceId'] = 'text_vminstinfo_does_not_exist_nf_id' + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.HEAL, ns_inst_id) + ns_heal_service = NSHealService(ns_inst_id, heal_ns_json, job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') diff --git a/lcm/ns/tests/test_ns_manual_scale.py b/lcm/ns/tests/test_ns_manual_scale.py index e25b4460..52417362 100644 --- a/lcm/ns/tests/test_ns_manual_scale.py +++ b/lcm/ns/tests/test_ns_manual_scale.py @@ -1,34 +1,34 @@ # Copyright 2017 ZTE Corporation. # -# Licensed under the Apache License, Version 2.0 (the "License"); +# 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, +# 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 +import time import uuid +import copy -import mock -from rest_framework.test import APIClient from django.test import TestCase +from rest_framework.test import APIClient from rest_framework import status from lcm.ns.biz.ns_manual_scale import NSManualScaleService from lcm.ns.enum import NS_INST_STATUS -from lcm.pub.database.models import NSInstModel, JobModel, NfInstModel +from lcm.pub.database.models import NSInstModel, JobModel, NfInstModel, NSLcmOpOccModel from lcm.pub.exceptions import NSLCMException -from lcm.pub.msapi import catalog -from lcm.pub.utils import restcall from lcm.pub.utils.jobutil import JobUtil -from lcm.jobs.enum import JOB_MODEL_STATUS, JOB_TYPE, JOB_ACTION -from lcm.ns.tests import SCALING_MAP_DICT, VNFD_MODEL_DICT, SCALE_NS_DICT +from lcm.jobs.enum import JOB_TYPE, JOB_ACTION, JOB_PROGRESS +from lcm.ns.tests import SCALING_MAP_DICT, SCALE_NS_THREAD_DICT, SCALE_NS_DICT +from lcm.ns_vnfs.enum import VNF_STATUS +from lcm.ns_vnfs.biz.scale_vnfs import NFManualScaleService class TestNsManualScale(TestCase): @@ -38,105 +38,135 @@ class TestNsManualScale(TestCase): self.ns_inst_id = str(uuid.uuid4()) self.job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.MANUAL_SCALE, self.ns_inst_id) self.client = APIClient() - self.package_id = "7" + self.package_id = '7' NSInstModel( id=self.ns_inst_id, - name="abc", + name='abc', nspackage_id=self.package_id, - nsd_id="111").save() + nsd_id='test_ns_manual_scale').save() + NfInstModel(package_id='nf_001', status=VNF_STATUS.ACTIVE, nfinstid='nf_001').save() + NfInstModel(package_id='nf_002', status=VNF_STATUS.ACTIVE, nfinstid='nf_002').save() def tearDown(self): NSInstModel.objects.filter().delete() + NfInstModel.objects.filter().delete() JobModel.objects.filter().delete() - - def insert_new_ns(self): - ns_inst_id = str(uuid.uuid4()) - job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.MANUAL_SCALE, self.ns_inst_id) - package_id = "23" - NSInstModel( - id=ns_inst_id, - name="abc", - nspackage_id=package_id, - nsd_id=package_id).save() - return ns_inst_id, job_id - - def insert_new_nf(self): - self.vnfm_inst_id = "1" - NfInstModel.objects.create( - nfinstid="233", - nf_name="name_1", - vnf_id="1", - vnfm_inst_id="1", - ns_inst_id=self.ns_inst_id, - max_cpu='14', - max_ram='12296', - max_hd='101', - max_shd="20", - max_net=10, - status='active', - mnfinstid="ab34-3g5j-de13-ab85-ij93", - package_id="nf_zte_hss", - vnfd_model=json.dumps(VNFD_MODEL_DICT)) + NSLcmOpOccModel.objects.filter().delete() @mock.patch.object(NSManualScaleService, 'run') - def test_ns_manual_scale(self, mock_run): - response = self.client.post("/api/nslcm/v1/ns/%s/scale" % self.ns_inst_id, data=SCALE_NS_DICT, format='json') + def test_ns_manual_scale_url(self, mock_run): + response = self.client.post('/api/nslcm/v1/ns/%s/scale' % self.ns_inst_id, data=SCALE_NS_DICT, format='json') self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code) - def test_ns_manual_scale_error_scaletype(self): - scale_ns_json = SCALE_NS_DICT.copy() - scale_ns_json["scaleType"] = "SCALE_ERR" - NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id).run() - jobs = JobModel.objects.filter(jobid=self.job_id) - self.assertEqual(255, jobs[0].progress) - - def test_ns_manual_scale_error_nsd_id(self): - scale_ns_json = SCALE_NS_DICT.copy() - scale_ns_json["scaleNsData"][0]["scaleNsByStepsData"][0]["aspectId"] = "sss_zte" - NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id).run() - jobs = JobModel.objects.filter(jobid=self.job_id) - self.assertEqual(255, jobs[0].progress) - - def test_ns_manual_scale_error_aspect(self): - scale_ns_json = SCALE_NS_DICT.copy() - scale_ns_json["scaleNsData"][0]["scaleNsByStepsData"][0]["aspectId"] = "sss_zte" - ns_inst_id, job_id = self.insert_new_ns() - job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.MANUAL_SCALE, ns_inst_id) - NSManualScaleService(ns_inst_id, scale_ns_json, job_id).run() - jobs = JobModel.objects.filter(jobid=job_id) - self.assertEqual(255, jobs[0].progress) - - @mock.patch.object(catalog, 'get_scalingmap_json_package') - @mock.patch.object(NSManualScaleService, 'do_vnfs_scale') - def test_ns_manual_scale_success(self, mock_do_vnfs_scale, mock_get_scalingmap_json_package): - scale_ns_json = SCALE_NS_DICT.copy() - scale_ns_json["scaleNsData"][0]["scaleNsByStepsData"][0]["aspectId"] = "TIC_EDGE_IMS" - mock_get_scalingmap_json_package.return_value = self.scaling_map_json - mock_do_vnfs_scale.return_value = JOB_MODEL_STATUS.FINISHED - ns_inst_id, job_id = self.insert_new_ns() - job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.MANUAL_SCALE, ns_inst_id) - self.insert_new_nf() - NSManualScaleService(ns_inst_id, scale_ns_json, job_id).run() - jobs = JobModel.objects.filter(jobid=job_id) - self.assertEqual(255, jobs[0].progress) - - @mock.patch.object(restcall, 'call_req') - def test_ns_manual_scale_thread(self, mock_call): - scale_ns_json = SCALE_NS_DICT.copy() - NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id).run() - self.assertTrue(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) - - @mock.patch.object(NSManualScaleService, 'start') - def test_ns_manual_scale_empty_data(self, mock_start): - mock_start.side_effect = NSLCMException("NS scale failed.") - response = self.client.post("/api/nslcm/v1/ns/%s/scale" % self.ns_inst_id, data={}, format='json') - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertIn("error", response.data) + @mock.patch.object(NSManualScaleService, 'run') + def test_ns_manual_scale_url_when_require_data_is_not_valid(self, mock_run): + response = self.client.post('/api/nslcm/v1/ns/%s/scale' % self.ns_inst_id, data={}, + format='json') + self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code) + self.assertIn('error', response.data) @mock.patch.object(NSManualScaleService, 'start') - def test_ns_manual_scale_when_ns_not_exist(self, mock_start): - mock_start.side_effect = NSLCMException("NS scale failed.") + def test_ns_manual_scale_url_when_ns_not_exist(self, mock_start): + mock_start.side_effect = NSLCMException('NS scale failed.') scale_ns_json = SCALE_NS_DICT.copy() - response = self.client.post("/api/nslcm/v1/ns/11/scale", data=scale_ns_json, format='json') + response = self.client.post('/api/nslcm/v1/ns/11/scale', data=scale_ns_json, format='json') self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - self.assertIn("error", response.data) + self.assertIn('error', response.data) + + @mock.patch('lcm.ns.biz.ns_manual_scale.get_scale_vnf_data_info_list') + @mock.patch.object(NFManualScaleService, 'run') + @mock.patch.object(time, 'sleep') + @mock.patch.object(JobModel.objects, 'get') + def test_ns_manual_scale_asynchronous_tasks_success(self, mock_get, mock_sleep, mock_run, mock_vnf_data_info_list): + mock_run.return_value = None + mock_sleep.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.FINISHED) + mock_vnf_data_info_list.return_value = [ + { + "vnfd_id": "nf_001", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "123" + }, + { + "vnfd_id": "nf_002", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "456" + } + ] + scale_ns_json = SCALE_NS_THREAD_DICT.copy() + ns_heal_service = NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id) + ns_heal_service.run() + jobs = JobModel.objects.filter(jobid=self.job_id) + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + self.assertEqual(JOB_PROGRESS.FINISHED, jobs[0].progress) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'COMPLETED') + + def test_ns_manual_scale_asynchronous_tasks_when_scale_ns_data_is_none(self): + scale_ns_json = SCALE_NS_THREAD_DICT.copy() + scale_ns_json['scaleNsData'] = None + ns_heal_service = NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id) + ns_heal_service.run() + jobs = JobModel.objects.filter(jobid=self.job_id) + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + self.assertEqual(JOB_PROGRESS.ERROR, jobs[0].progress) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_manual_scale_asynchronous_tasks_when_scale_ns_by_steps_data_is_none(self): + scale_ns_json = copy.deepcopy(SCALE_NS_THREAD_DICT) + scale_ns_json['scaleNsData']["scaleNsByStepsData"] = None + ns_heal_service = NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id) + ns_heal_service.run() + jobs = JobModel.objects.filter(jobid=self.job_id) + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + self.assertEqual(JOB_PROGRESS.ERROR, jobs[0].progress) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + @mock.patch('lcm.ns.biz.ns_manual_scale.get_scale_vnf_data_info_list') + @mock.patch.object(NFManualScaleService, 'run') + @mock.patch.object(time, 'sleep') + @mock.patch.object(JobModel.objects, 'get') + def test_ns_manual_scale_asynchronous_tasks_when_vnf_scale_failed(self, mock_get, mock_sleep, + mock_run, mock_vnf_data_info_list): + scale_ns_json = SCALE_NS_THREAD_DICT.copy() + mock_run.return_value = None + mock_sleep.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.ERROR) + mock_vnf_data_info_list.return_value = [ + { + "vnfd_id": "nf_001", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "123" + }, + { + "vnfd_id": "nf_002", + "vnf_scaleAspectId": "gpu", + "numberOfSteps": "456" + } + ] + ns_heal_service = NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id) + ns_heal_service.run() + jobs = JobModel.objects.filter(jobid=self.job_id) + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + self.assertEqual(JOB_PROGRESS.ERROR, jobs[0].progress) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_manual_scale_asynchronous_tasks_when_error_scale_type(self): + scale_ns_json = SCALE_NS_THREAD_DICT.copy() + scale_ns_json['scaleType'] = 'SCALE_ERR' + ns_heal_service = NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id) + ns_heal_service.run() + jobs = JobModel.objects.filter(jobid=self.job_id) + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + self.assertEqual(JOB_PROGRESS.ERROR, jobs[0].progress) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + @mock.patch('lcm.ns.biz.ns_manual_scale.get_scale_vnf_data_info_list') + def test_ns_manual_scale_asynchronous_tasks_when_failed_to_get_scale_vnf_data_parameter(self, mock_vnf_data_info): + mock_vnf_data_info.return_value = [] + scale_ns_json = SCALE_NS_THREAD_DICT.copy() + ns_heal_service = NSManualScaleService(self.ns_inst_id, scale_ns_json, self.job_id) + ns_heal_service.run() + jobs = JobModel.objects.filter(jobid=self.job_id) + self.assertEqual(NSInstModel.objects.get(id=self.ns_inst_id).status, NS_INST_STATUS.ACTIVE) + self.assertEqual(JOB_PROGRESS.ERROR, jobs[0].progress) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') diff --git a/lcm/ns/tests/test_ns_terminate.py b/lcm/ns/tests/test_ns_terminate.py new file mode 100644 index 00000000..24d0e117 --- /dev/null +++ b/lcm/ns/tests/test_ns_terminate.py @@ -0,0 +1,146 @@ +import mock +import time +import httplib2 + +from django.test import TestCase +from rest_framework.test import APIClient + +from lcm.jobs.enum import JOB_TYPE, JOB_ACTION, JOB_PROGRESS +from lcm.ns.biz.ns_terminate import TerminateNsService +from lcm.ns.enum import OWNER_TYPE +from lcm.ns.tests import TERMINATE_NS_DICT +from lcm.pub.database.models import NSInstModel, JobModel, FPInstModel, NfInstModel, VLInstModel, PNFInstModel +from lcm.pub.utils.jobutil import JobUtil + + +class TestScaleAspect(TestCase): + def setUp(self): + self.client = APIClient() + self.ns_inst_id = 'test_ns_terminate_001' + self.url = '/api/nslcm/v1/ns/%s/terminate' % self.ns_inst_id + self.job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, self.ns_inst_id) + NSInstModel(id=self.ns_inst_id).save() + NSInstModel(id='test_ns_terminate_002').save() + FPInstModel(nsinstid=self.ns_inst_id, sfcid='test_sfc_inst_001', fpname='xxx', status='zzz').save() + NfInstModel(ns_inst_id=self.ns_inst_id).save() + VLInstModel(ownertype=OWNER_TYPE.NS, ownerid=self.ns_inst_id).save() + PNFInstModel(nsInstances=self.ns_inst_id).save() + + def tearDown(self): + NSInstModel.objects.all().delete() + FPInstModel.objects.all().delete() + NfInstModel.objects.all().delete() + VLInstModel.objects.all().delete() + PNFInstModel.objects.all().delete() + JobModel.objects.all().delete() + + def test_ns_terminate_asynchronous_tasks_when_ns_does_not_exist(self): + ns_instance_id = 'test_ns_terminate_not_exist' + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, ns_instance_id) + TerminateNsService(ns_instance_id, job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.FINISHED) + + def test_ns_terminate_asynchronous_tasks_with_none(self): + ns_instance_id = 'test_ns_terminate_002' + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, ns_instance_id) + TerminateNsService(ns_instance_id, job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.FINISHED) + + @mock.patch.object(time, 'sleep') + @mock.patch.object(httplib2.Http, 'request') + def test_ns_terminate_asynchronous_tasks(self, mock_request, mock_sleep): + mock_request.side_effect = [ + ({'status': '200'}, '{"result": "0"}'.encode('utf-8')), + ({'status': '200'}, '{"jobId": "zzz"}'.encode('utf-8')), + ({'status': '200'}, '{"responseDescriptor": {"progress": 100, "responseId": 1, ' + '"statusDescription": ""}}'.encode('utf-8')), + ({'status': '200'}, '{"result": "0"}'.encode('utf-8')), + ({'status': '200'}, '{"result": "0"}'.encode('utf-8')) + ] + mock_sleep.return_value = None + + TerminateNsService(self.ns_inst_id, self.job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.FINISHED) + + @mock.patch.object(time, 'sleep') + @mock.patch.object(httplib2.Http, 'request') + def test_ns_terminate_asynchronous_tasks_when_cancel_vnf_no_vnfjobid(self, mock_request, mock_sleep): + ns_instance_id = 'test_ns_terminate_when_cancel_vnf_no_vnfjobid' + NSInstModel(id=ns_instance_id).save() + NfInstModel(ns_inst_id=ns_instance_id).save() + mock_request.side_effect = [ + ({'status': '200'}, '{"jobId": ""}'.encode('utf-8')) + ] + mock_sleep.return_value = None + + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, ns_instance_id) + TerminateNsService(ns_instance_id, job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.FINISHED) + + @mock.patch.object(time, 'sleep') + @mock.patch.object(httplib2.Http, 'request') + def test_ns_terminate_asynchronous_tasks_when_terminate_vnf_failed(self, mock_request, mock_sleep): + ns_instance_id = 'test_ns_terminate_when_terminate_vnf_failed' + NSInstModel(id=ns_instance_id).save() + NfInstModel(ns_inst_id=ns_instance_id).save() + mock_request.side_effect = [ + ({'status': '404'}, '{"jobId": "zzz"}'.encode('utf-8')) + ] + mock_sleep.return_value = None + + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, ns_instance_id) + TerminateNsService(ns_instance_id, job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.FINISHED) + + @mock.patch.object(time, 'sleep') + @mock.patch.object(httplib2.Http, 'request') + def test_ns_terminate_asynchronous_tasks_when_failed_to_query_job(self, mock_request, mock_sleep): + ns_instance_id = 'test_ns_terminate_when_failed_to_query_job' + NSInstModel(id=ns_instance_id).save() + NfInstModel(ns_inst_id=ns_instance_id).save() + mock_request.side_effect = [ + ({'status': '200'}, '{"jobId": "zzz"}'.encode('utf-8')), + ({'status': '400'}), + ({'status': '200'}, '{"responseDescriptor": {"progress": 100, "responseId": 1, ' + '"statusDescription": ""}}'.encode('utf-8')) + ] + mock_sleep.return_value = None + + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, ns_instance_id) + TerminateNsService(ns_instance_id, job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.FINISHED) + + @mock.patch.object(time, 'sleep') + @mock.patch.object(httplib2.Http, 'request') + def test_ns_terminate_asynchronous_tasks_when_no_new_progress(self, mock_request, mock_sleep): + ns_instance_id = 'test_ns_terminate_when_no_new_progress' + NSInstModel(id=ns_instance_id).save() + NfInstModel(ns_inst_id=ns_instance_id).save() + mock_request.side_effect = [ + ({'status': '200'}, '{"jobId": "zzz"}'.encode('utf-8')), + ({'status': '200'}, '{}'.encode('utf-8')), + ({'status': '200'}, '{"responseDescriptor": {"progress": 100, "responseId": 1, ' + '"statusDescription": ""}}'.encode('utf-8')) + ] + mock_sleep.return_value = None + + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, ns_instance_id) + TerminateNsService(ns_instance_id, job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.FINISHED) + + @mock.patch.object(time, 'sleep') + @mock.patch.object(httplib2.Http, 'request') + def test_ns_terminate_asynchronous_tasks_when_job_failed(self, mock_request, mock_sleep): + ns_instance_id = 'test_ns_terminate_when_job_failed' + NSInstModel(id=ns_instance_id).save() + NfInstModel(ns_inst_id=ns_instance_id).save() + mock_request.side_effect = [ + ({'status': '200'}, '{"jobId": "zzz"}'.encode('utf-8')), + ({'status': '200'}, '{"responseDescriptor": {"progress": 255, "responseId": 1, ' + '"statusDescription": ""}}'.encode('utf-8')) + ] + mock_sleep.return_value = None + + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.TERMINATE, ns_instance_id) + TerminateNsService(ns_instance_id, job_id, TERMINATE_NS_DICT).run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.FINISHED) diff --git a/lcm/ns/tests/test_ns_update.py b/lcm/ns/tests/test_ns_update.py new file mode 100644 index 00000000..f18a4535 --- /dev/null +++ b/lcm/ns/tests/test_ns_update.py @@ -0,0 +1,129 @@ +import mock +import time + +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework import status + +from lcm.jobs.enum import JOB_TYPE, JOB_ACTION, JOB_PROGRESS +from lcm.ns.biz.ns_update import NSUpdateService +from lcm.ns.enum import NS_INST_STATUS +from lcm.ns.tests import UPDATE_NS_DICT +from lcm.ns_vnfs.biz.update_vnfs import NFOperateService +from lcm.pub.database.models import NSInstModel, JobModel, NSLcmOpOccModel +from lcm.pub.utils.jobutil import JobUtil + + +class TestScaleAspect(TestCase): + def setUp(self): + self.client = APIClient() + self.ns_inst_id = 'test_ns_update_001' + self.url = '/api/nslcm/v1/ns/%s/update' % self.ns_inst_id + self.job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.HEAL, self.ns_inst_id) + NSInstModel(id=self.ns_inst_id).save() + + def tearDown(self): + NSInstModel.objects.all().delete() + JobModel.objects.all().delete() + + def test_ns_update_when_require_is_not_valid(self): + response = self.client.post(self.url, data={}, format='json') + self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code) + + @mock.patch.object(NSUpdateService, 'run') + def test_ns_update_url(self, mock_run): + mock_run.return_value = None + response = self.client.post(self.url, data=UPDATE_NS_DICT, format='json') + self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code) + + @mock.patch.object(JobUtil, 'create_job') + @mock.patch.object(NSUpdateService, 'run') + def test_ns_update_url_nslcmexception(self, mock_run, mock_create_job): + mock_run.return_value = None + mock_create_job.return_value = None + response = self.client.post(self.url, data=UPDATE_NS_DICT, format='json') + self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code) + + @mock.patch.object(time, 'sleep') + @mock.patch.object(NFOperateService, 'run') + @mock.patch.object(JobModel.objects, 'get') + def test_ns_update_asynchronous_tasks(self, mock_get, mock_run, mock_sleep): + mock_sleep.return_value = None + mock_run.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.FINISHED) + ns_heal_service = NSUpdateService(self.ns_inst_id, UPDATE_NS_DICT, self.job_id) + ns_heal_service.run() + self.assertEqual(NSInstModel.objects.filter(id=self.ns_inst_id).first().status, NS_INST_STATUS.ACTIVE) + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.FINISHED) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'COMPLETED') + + @mock.patch.object(time, 'sleep') + @mock.patch.object(NFOperateService, 'run') + @mock.patch.object(JobModel.objects, 'get') + def test_ns_update_asynchronous_tasks_when_nf_update_error(self, mock_get, mock_run, mock_sleep): + mock_sleep.return_value = None + mock_run.return_value = None + mock_get.return_value = JobModel(progress=JOB_PROGRESS.ERROR) + ns_heal_service = NSUpdateService(self.ns_inst_id, UPDATE_NS_DICT, self.job_id) + ns_heal_service.run() + self.assertEqual(NSInstModel.objects.filter(id=self.ns_inst_id).first().status, NS_INST_STATUS.UPDATING) + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_update_asynchronous_tasks_when_ns_does_not_exist(self): + ns_instance_id = 'test_ns_update_002' + job_id = JobUtil.create_job(JOB_TYPE.NS, JOB_ACTION.UPDATE, ns_instance_id) + ns_heal_service = NSUpdateService(ns_instance_id, UPDATE_NS_DICT, job_id) + ns_heal_service.run() + self.assertEqual(JobModel.objects.filter(jobid=job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_update_asynchronous_tasks_when_updatetype_parameter_does_not_exist(self): + request_data = {"updateType": ""} + ns_heal_service = NSUpdateService(self.ns_inst_id, request_data, self.job_id) + ns_heal_service.run() + self.assertEqual(NSInstModel.objects.filter(id=self.ns_inst_id).first().status, None) + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_update_asynchronous_tasks_when_updatetype_not_operate_vnf(self): + request_data = {"updateType": "ADD_VNF"} + ns_heal_service = NSUpdateService(self.ns_inst_id, request_data, self.job_id) + ns_heal_service.run() + self.assertEqual(NSInstModel.objects.filter(id=self.ns_inst_id).first().status, NS_INST_STATUS.UPDATING) + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_update_asynchronous_tasks_when_operatevnfdata_does_not_exist(self): + request_data = {"updateType": "OPERATE_VNF"} + ns_heal_service = NSUpdateService(self.ns_inst_id, request_data, self.job_id) + ns_heal_service.run() + self.assertEqual(NSInstModel.objects.filter(id=self.ns_inst_id).first().status, NS_INST_STATUS.UPDATING) + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_update_asynchronous_tasks_when_vnfinstanceid_does_not_exist(self): + request_data = { + "updateType": "OPERATE_VNF", + "OperateVnfData": [{}] + } + ns_heal_service = NSUpdateService(self.ns_inst_id, request_data, self.job_id) + ns_heal_service.run() + self.assertEqual(NSInstModel.objects.filter(id=self.ns_inst_id).first().status, NS_INST_STATUS.UPDATING) + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') + + def test_ns_update_asynchronous_tasks_when_changestateto_does_not_exist(self): + request_data = { + "updateType": "OPERATE_VNF", + "OperateVnfData": [ + { + "vnfInstanceId": "test_vnf_001" + } + ] + } + ns_heal_service = NSUpdateService(self.ns_inst_id, request_data, self.job_id) + ns_heal_service.run() + self.assertEqual(NSInstModel.objects.filter(id=self.ns_inst_id).first().status, NS_INST_STATUS.UPDATING) + self.assertEqual(JobModel.objects.filter(jobid=self.job_id).first().progress, JOB_PROGRESS.ERROR) + self.assertEqual(NSLcmOpOccModel.objects.filter(id=ns_heal_service.occ_id).first().operation_state, 'FAILED') diff --git a/lcm/ns/tests/test_scaleaspect.py b/lcm/ns/tests/test_scaleaspect.py index 00e1baaa..f44e7544 100644 --- a/lcm/ns/tests/test_scaleaspect.py +++ b/lcm/ns/tests/test_scaleaspect.py @@ -1,200 +1,119 @@ # Copyright 2016-2018 ZTE Corporation. # -# Licensed under the Apache License, Version 2.0 (the "License"); +# 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, +# 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 mock +import os -import json from django.test import TestCase -from lcm.pub.database.models import NSInstModel -from lcm.pub.database.models import NfInstModel -from lcm.pub.utils.timeutil import now_time -from lcm.ns.tests import VNFD_MODEL_DICT +from lcm.pub.database.models import NSInstModel, NfInstModel +from lcm.ns_vnfs.enum import VNF_STATUS +from lcm.ns.biz.scaleaspect import mapping_conv, get_vnf_instance_id_list, check_scale_list, get_scale_vnf_data, \ + get_nsdId, check_and_set_params, get_scale_vnf_data_info_list, get_vnf_scale_info, get_scale_vnf_data_from_json class TestScaleAspect(TestCase): def setUp(self): - self.initInstModel() + pass - self.init_scale_ns_data() - - self.vnf_scale_info_list = [ + def tearDown(self): + NSInstModel.objects.all().delete() + NfInstModel.objects.all().delete() + + def test_mapping_conv(self): + keyword_map = {'a': 1, 'b': 2, 'c': 3, 'd': {'d.1': 'd.1'}} + rest_return = {'b': 2, 'C': 3} + resp_data = mapping_conv(keyword_map, rest_return) + self.assertEqual(resp_data, {'a': '', 'b': 2, 'c': 3, 'd': {'d.1': ''}}) + + def test_get_vnf_instance_id_list_when_no_model(self): + self.assertEqual(get_vnf_instance_id_list('package_1'), []) + + def test_check_scale_list_when_empty_vnf_scale_list(self): + try: + check_scale_list([], 'ns_instanceId_01', '', '') + except Exception as e: + self.assertEqual(e.args, ('The scaling option[ns=ns_instanceId_01, aspect=, step=] does not exist. ' + 'Pls check the config file.',)) + + @mock.patch.object(os.path, 'abspath') + def test_get_scale_vnf_data(self, mock_abspath): + mock_abspath.return_value = 'lcm/1/2/3.py' + scale_ns_data = {'scaleNsByStepsData': {'aspectId': 'TIC_EDGE_IMS', 'numberOfSteps': 1, + 'scalingDirection': 'r'}} + ns_instance_id = 'ns_instanceId_01' + scale_vnf_data_list = get_scale_vnf_data(scale_ns_data, ns_instance_id) + success_list = [ { - "vnfd_id": "nf_zte_cscf", - "vnf_scaleAspectId": "mpu", - "numberOfSteps": "1" + 'vnfInstanceId': 'nf_zte_cscf', + 'scaleByStepData': { + 'type': 'r', + 'aspectId': 'gsu', + 'numberOfSteps': '1' + } }, { - "vnfd_id": "nf_zte_hss", - "vnf_scaleAspectId": "gsu", - "numberOfSteps": "2" + 'vnfInstanceId': 'nf_zte_hss', + 'scaleByStepData': { + 'type': 'r', + 'aspectId': 'gpu', + 'numberOfSteps': '3' + } } ] - - def init_scale_ns_data(self): - self.ns_scale_aspect = "TIC_EDGE_IMS" - self.ns_scale_steps = "1" - self.ns_scale_direction = "SCALE_IN" - self.scaleNsData = [{ - "scaleNsByStepsData": [ - { - "aspectId": self.ns_scale_aspect, - "numberOfSteps": self.ns_scale_steps, - "scalingDirection": self.ns_scale_direction - } - ] - }] - - self.ns_scale_aspect2 = "TIC_EDGE_HW" - self.ns_scale_steps2 = "4" - self.scaleNsData2 = [{ - "scaleNsByStepsData": [ - { - "aspectId": self.ns_scale_aspect2, - "numberOfSteps": self.ns_scale_steps2, - "scalingDirection": self.ns_scale_direction + self.assertEqual(scale_vnf_data_list, success_list) + + def test_get_nsd_id_when_none(self): + self.assertEqual(get_nsdId('ns_instance_id_01'), None) + + def test_check_and_set_params_when_scale_ns_data_is_none(self): + try: + check_and_set_params(None, '') + except Exception as e: + self.assertEqual(e.args, ('Error! scaleNsData in the request is Empty!',)) + + def test_check_and_set_params_when_scale_ns_by_steps_data_is_none(self): + scale_ns_data = {'scaleNsByStepsData': None} + try: + check_and_set_params(scale_ns_data, '') + except Exception as e: + self.assertEqual(e.args, ('Error! scaleNsByStepsData in the request is Empty!',)) + + @mock.patch.object(os.path, 'abspath') + def test_get_scale_vnf_data_info_list(self, mock_abspath): + NSInstModel(id='ns_instanceId_02', nsd_id='02').save() + NfInstModel(package_id='nf_hw_cscf', status=VNF_STATUS.ACTIVE, nfinstid='nfinst_01').save() + mock_abspath.return_value = 'lcm/1/2/3.py' + scale_ns_data = { + 'scaleNsByStepsData': {'aspectId': 'TIC_EDGE_HW', 'numberOfSteps': 4, 'scalingDirection': 'r'}} + ns_instance_id = 'ns_instanceId_02' + scale_vnf_data_info_list = get_scale_vnf_data_info_list(scale_ns_data, ns_instance_id) + success_list = [ + { + 'vnfInstanceId': 'nfinst_01', + 'scaleByStepData': { + 'type': 'r', + 'aspectId': 'gsu', + 'numberOfSteps': '1' } - ] - }] - - def initInstModel(self): - self.nsd_id = "23" - self.ns_inst_id = "1" - self.ns_name = "ns_1" - self.ns_package_id = "ns_zte" - self.description = "ns_zte" - self.global_customer_id = "global_customer_id" - self.service_type = "service_role" - - NSInstModel(id=self.ns_inst_id, - name=self.ns_name, - nspackage_id=self.ns_package_id, - nsd_id=self.nsd_id, - description=self.description, - status='empty', - lastuptime=now_time(), - global_customer_id=self.global_customer_id, - service_type=self.service_type).save() - - self.nf_inst_id = "231" - self.ns_inst_id = "1" - self.nf_name = "name_1" - self.vnf_id = "1" - self.vnfm_inst_id = "1" - self.package_id = "nf_zte_cscf" - self.nf_uuid = "abc34-345a-de13-ab85-ijs9" - - NfInstModel.objects.create( - nfinstid=self.nf_inst_id, - nf_name=self.nf_name, - vnf_id=self.vnf_id, - vnfm_inst_id=self.vnfm_inst_id, - ns_inst_id=self.ns_inst_id, - max_cpu='14', - max_ram='12296', - max_hd='101', - max_shd="20", - max_net=10, - status='active', - mnfinstid=self.nf_uuid, - package_id=self.package_id, - vnfd_model=json.dumps(VNFD_MODEL_DICT)) - - # Create a second vnf instance - self.nf_inst_id = "232" - self.package_id = "nf_zte_hss" - self.nf_uuid = "abc34-3g5a-de13-ab85-ijs3" - - NfInstModel.objects.create( - nfinstid=self.nf_inst_id, - nf_name=self.nf_name, - vnf_id=self.vnf_id, - vnfm_inst_id=self.vnfm_inst_id, - ns_inst_id=self.ns_inst_id, - max_cpu='14', - max_ram='12296', - max_hd='101', - max_shd="20", - max_net=10, - status='active', - mnfinstid=self.nf_uuid, - package_id=self.package_id, - vnfd_model=json.dumps(VNFD_MODEL_DICT)) - - def add_another_nf_instance(self): - # Create a third vnf instance - nf_inst_id = "233" - package_id = "nf_zte_hss" - nf_uuid = "ab34-3g5j-de13-ab85-ij93" - - NfInstModel.objects.create( - nfinstid=nf_inst_id, - nf_name=self.nf_name, - vnf_id=self.vnf_id, - vnfm_inst_id=self.vnfm_inst_id, - ns_inst_id=self.ns_inst_id, - max_cpu='14', - max_ram='12296', - max_hd='101', - max_shd="20", - max_net=10, - status='active', - mnfinstid=nf_uuid, - package_id=package_id, - vnfd_model=json.dumps(VNFD_MODEL_DICT)) - - def add_new_vnf_instance(self): - # Create a third vnf instance - nf_inst_id = "241" - package_id = "nf_hw_cscf" - nf_uuid = "ab34-3g5j-de13-aa85-ij93" - - NfInstModel.objects.create( - nfinstid=nf_inst_id, - nf_name=self.nf_name, - vnf_id=self.vnf_id, - vnfm_inst_id=self.vnfm_inst_id, - ns_inst_id=self.ns_inst_id, - max_cpu='14', - max_ram='12296', - max_hd='101', - max_shd="20", - max_net=10, - status='active', - mnfinstid=nf_uuid, - package_id=package_id, - vnfd_model=json.dumps(VNFD_MODEL_DICT)) - - # Create a third vnf instance - nf_inst_id = "242" - package_id = "nf_hw_hss" - nf_uuid = "ab34-3g5j-de13-aa85-id93" + } + ] + self.assertEqual(scale_vnf_data_info_list, success_list) - NfInstModel.objects.create( - nfinstid=nf_inst_id, - nf_name=self.nf_name, - vnf_id=self.vnf_id, - vnfm_inst_id=self.vnfm_inst_id, - ns_inst_id=self.ns_inst_id, - max_cpu='14', - max_ram='12296', - max_hd='101', - max_shd="20", - max_net=10, - status='active', - mnfinstid=nf_uuid, - package_id=package_id, - vnfd_model=json.dumps(VNFD_MODEL_DICT)) + def test_get_vnf_scale_info_when_return_none(self): + filename = 'lcm/ns/tests/data/scalemapping.json' + ns_instance_id = 'ns_instanceId_03' + self.assertEqual(get_vnf_scale_info(filename, ns_instance_id, '', ''), None) - def tearDown(self): - NSInstModel().clean() - NfInstModel().clean() + def test_get_scale_vnf_data_from_json_when_return_none(self): + self.assertEqual(get_scale_vnf_data_from_json({}, '', '', ''), None) -- cgit 1.2.3-korg