1 # Copyright 2016-2017 ZTE Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
18 from django.test import TestCase, Client
19 from rest_framework import status
21 from lcm.pub.database.models import NfInstModel, JobModel, NSInstModel, VmInstModel, OOFDataModel, SubscriptionModel
22 from lcm.pub.exceptions import NSLCMException
23 from lcm.pub.utils import restcall
24 from lcm.pub.utils.jobutil import JOB_MODEL_STATUS
25 from lcm.pub.utils.jobutil import JobUtil, JOB_TYPE
26 from lcm.pub.utils.timeutil import now_time
27 from lcm.pub.utils.values import ignore_case_get
28 from lcm.ns_vnfs.biz.create_vnfs import CreateVnfs
29 from lcm.ns_vnfs.biz.grant_vnf import GrantVnf
30 from lcm.ns_vnfs.biz.heal_vnfs import NFHealService
31 from lcm.ns_vnfs.biz.scale_vnfs import NFManualScaleService
32 from lcm.ns_vnfs.biz.subscribe import SubscriptionDeletion
33 from lcm.ns_vnfs.biz.terminate_nfs import TerminateVnfs
34 from lcm.ns_vnfs.const import VNF_STATUS, INST_TYPE
35 from lcm.ns_vnfs.biz import create_vnfs
36 from lcm.ns_vnfs.biz.place_vnfs import PlaceVnfs
37 from lcm.pub.msapi import resmgr
40 class TestGetVnfViews(TestCase):
42 self.client = Client()
43 self.nf_inst_id = str(uuid.uuid4())
44 NfInstModel(nfinstid=self.nf_inst_id, nf_name='vnf1', vnfm_inst_id='1', vnf_id='vnf_id1',
45 status=VNF_STATUS.ACTIVE, create_time=now_time(), lastuptime=now_time()).save()
48 NfInstModel.objects.all().delete()
50 def test_get_vnf(self):
51 response = self.client.get("/api/nslcm/v1/ns/vnfs/%s" % self.nf_inst_id)
52 self.failUnlessEqual(status.HTTP_200_OK, response.status_code)
53 context = json.loads(response.content)
54 self.failUnlessEqual(self.nf_inst_id, context['vnfInstId'])
57 class TestCreateVnfViews(TestCase):
59 self.ns_inst_id = str(uuid.uuid4())
60 self.job_id = str(uuid.uuid4())
62 "nsInstanceId": self.ns_inst_id,
63 "additionalParamForNs": {
64 "inputs": json.dumps({
68 "additionalParamForVnf": [
70 "vnfprofileid": "VBras",
72 "inputs": json.dumps({
76 "vnfminstanceid": "1",
83 self.client = Client()
84 NSInstModel(id=self.ns_inst_id, name='ns', nspackage_id='1', nsd_id='nsd_id', description='description',
85 status='instantiating', nsd_model=json.dumps(nsd_model_dict), create_time=now_time(),
86 lastuptime=now_time()).save()
89 NfInstModel.objects.all().delete()
90 JobModel.objects.all().delete()
92 @mock.patch.object(CreateVnfs, 'run')
93 def test_create_vnf(self, mock_run):
94 response = self.client.post("/api/nslcm/v1/ns/vnfs", data=self.data)
95 self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
96 context = json.loads(response.content)
97 self.assertTrue(NfInstModel.objects.filter(nfinstid=context['vnfInstId']).exists())
99 @mock.patch.object(restcall, 'call_req')
100 def test_create_vnf_thread(self, mock_call_req):
101 nf_inst_id, job_id = create_vnfs.prepare_create_params()
103 "/api/ztevnfmdriver/v1/1/vnfs":
104 [0, json.JSONEncoder().encode({"jobId": self.job_id, "vnfInstanceId": 3}), '200'],
105 "/api/catalog/v1/vnfpackages/zte_vbras":
106 [0, json.JSONEncoder().encode(nf_package_info), '200'],
107 "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all":
108 [0, json.JSONEncoder().encode(vnfm_info), '200'],
109 "/api/resmgr/v1/vnf":
110 [0, json.JSONEncoder().encode({}), '200'],
111 "/api/resmgr/v1/vnfinfo":
112 [0, json.JSONEncoder().encode({}), '200'],
113 "/network/generic-vnfs/generic-vnf/%s" % nf_inst_id:
114 [0, json.JSONEncoder().encode({}), '201'],
115 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test?depth=all":
116 [0, json.JSONEncoder().encode(vim_info), '201'],
117 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1":
118 [0, json.JSONEncoder().encode({}), '201'],
119 "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0":
120 [0, json.JSONEncoder().encode({"jobid": self.job_id,
121 "responsedescriptor": {"progress": "100",
122 "status": JOB_MODEL_STATUS.FINISHED,
124 "statusdescription": "creating",
126 "responsehistorylist": [
128 "status": JOB_MODEL_STATUS.PROCESSING,
130 "statusdescription": "creating",
131 "errorcode": "0"}]}}), '200']}
133 def side_effect(*args):
134 return mock_vals[args[4]]
135 mock_call_req.side_effect = side_effect
137 'ns_instance_id': ignore_case_get(self.data, 'nsInstanceId'),
138 'additional_param_for_ns': ignore_case_get(self.data, 'additionalParamForNs'),
139 'additional_param_for_vnf': ignore_case_get(self.data, 'additionalParamForVnf'),
140 'vnf_index': ignore_case_get(self.data, 'vnfIndex')
142 CreateVnfs(data, nf_inst_id, job_id).run()
143 self.assertTrue(NfInstModel.objects.get(nfinstid=nf_inst_id).status, VNF_STATUS.ACTIVE)
145 @mock.patch.object(restcall, 'call_req')
146 @mock.patch.object(CreateVnfs, 'build_homing_request')
147 def test_send_homing_request(self, mock_build_req, mock_call_req):
148 nf_inst_id, job_id = create_vnfs.prepare_create_params()
149 OOFDataModel.objects.all().delete()
152 "transactionId": "1234",
153 "requestStatus": "accepted"
155 mock_build_req.return_value = {
157 "transactionId": "1234",
161 "requestType": "create",
163 "optimizers": ["placement"],
167 "placementDemands": [
169 "resourceModuleName": "vG",
170 "serviceResourceId": "1234",
171 "resourceModelInfo": {
172 "modelInvariantId": "1234",
173 "modelVersionId": "1234"
179 "serviceInstanceId": "1234",
180 "serviceName": "1234",
182 "modelInvariantId": "5678",
183 "modelVersionId": "7890"
187 mock_call_req.return_value = [0, json.JSONEncoder().encode(resp), '202']
189 'ns_instance_id': ignore_case_get(self.data, 'nsInstanceId'),
190 'additional_param_for_ns': ignore_case_get(self.data, 'additionalParamForNs'),
191 'additional_param_for_vnf': ignore_case_get(self.data, 'additionalParamForVnf'),
192 'vnf_index': ignore_case_get(self.data, 'vnfIndex')
194 CreateVnfs(data, nf_inst_id, job_id).send_homing_request_to_OOF()
195 ret = OOFDataModel.objects.filter(request_id="1234", transaction_id="1234")
196 self.assertIsNotNone(ret)
199 class TestTerminateVnfViews(TestCase):
201 self.client = Client()
202 self.ns_inst_id = str(uuid.uuid4())
203 self.nf_inst_id = '1'
204 self.vnffg_id = str(uuid.uuid4())
205 self.vim_id = str(uuid.uuid4())
206 self.job_id = str(uuid.uuid4())
208 self.tenant = "tenantname"
212 "vnfdName": "PGW001",
213 "vnfProvider": "zte",
214 "vnfdVersion": "V00001",
215 "vnfVersion": "V5.10.20",
218 "description": "PGW VNFD description",
220 "vnfExtendType": "driver"
223 NSInstModel.objects.all().delete()
224 NfInstModel.objects.all().delete()
225 VmInstModel.objects.all().delete()
226 NSInstModel(id=self.ns_inst_id, name="ns_name").save()
227 NfInstModel.objects.create(nfinstid=self.nf_inst_id,
231 ns_inst_id='111,2-2-2',
238 mnfinstid=self.nf_uuid,
240 vnfd_model=self.vnfd_model)
241 VmInstModel.objects.create(vmid="1",
244 insttype=INST_TYPE.VNF,
245 instid=self.nf_inst_id,
250 NSInstModel.objects.all().delete()
251 NfInstModel.objects.all().delete()
253 @mock.patch.object(TerminateVnfs, 'run')
254 def test_terminate_vnf_url(self, mock_run):
256 "terminationType": "forceful",
257 "gracefulTerminationTimeout": "600"}
259 response = self.client.post("/api/nslcm/v1/ns/terminatevnf/%s" % self.nf_inst_id, data=req_data)
260 self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
262 @mock.patch.object(restcall, 'call_req')
263 @mock.patch.object(SubscriptionDeletion, 'send_subscription_deletion_request')
264 def test_terminate_vnf(self, mock_send_subscription_deletion_request, mock_call_req):
265 job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, self.nf_inst_id)
267 nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
269 self.failUnlessEqual(1, 1)
271 self.failUnlessEqual(1, 0)
273 notification_types = ["VnfLcmOperationOccurrenceNotification"],
294 vnf_instance_subscription_filter = {
296 "vnfInstanceIds": '1',
297 "vnfInstanceNames": [],
298 "vnfProductsFromProviders": {}
300 SubscriptionModel.objects.create(
302 notification_types=json.dumps(notification_types),
303 operation_types=json.dumps(operation_types),
304 operation_states=json.dumps(operation_states),
305 vnf_instance_filter=json.dumps(vnf_instance_subscription_filter),
307 # links=json.dumps(...)
311 "vnf-id": "vnf-id-test111",
312 "vnf-name": "vnf-name-test111",
313 "vnf-type": "vnf-type-test111",
315 "is-closed-loop-disabled": False,
316 "resource-version": "1505465356262"
320 "responsedescriptor": {
322 "status": JOB_MODEL_STATUS.FINISHED,
324 "statusdescription": "creating",
326 "responsehistorylist": [
329 "status": JOB_MODEL_STATUS.PROCESSING,
331 "statusdescription": "creating",
339 "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all":
340 [0, json.JSONEncoder().encode(vnfm_info), '200'],
341 "/api/ztevnfmdriver/v1/1/vnfs/111/terminate":
342 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
343 "/api/resmgr/v1/vnf/1":
344 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
345 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test?depth=all":
346 [0, json.JSONEncoder().encode(vim_info), '201'],
347 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1?depth=all":
348 [0, json.JSONEncoder().encode(vserver_info), '201'],
349 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1?resource-version=1505465356263":
350 [0, json.JSONEncoder().encode({}), '200'],
351 "/api/ztevnfmdriver/v1/1/jobs/" + job_id + "?responseId=0":
352 [0, json.JSONEncoder().encode(job_info), '200'],
353 "/network/generic-vnfs/generic-vnf/1?depth=all":
354 [0, json.JSONEncoder().encode(vnf_info), '200'],
355 "/network/generic-vnfs/generic-vnf/1?resource-version=1505465356262":
356 [0, json.JSONEncoder().encode({}), '200']
359 def side_effect(*args):
360 return mock_vals[args[4]]
362 mock_call_req.side_effect = side_effect
365 "terminationType": "forceful",
366 "gracefulTerminationTimeout": "600"
369 TerminateVnfs(req_data, self.nf_inst_id, job_id).run()
370 nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
372 self.failUnlessEqual(1, 0)
374 self.failUnlessEqual(1, 1)
377 class TestScaleVnfViews(TestCase):
379 self.client = Client()
380 self.ns_inst_id = str(uuid.uuid4())
381 self.nf_inst_id = str(uuid.uuid4())
382 self.vnffg_id = str(uuid.uuid4())
383 self.vim_id = str(uuid.uuid4())
384 self.job_id = str(uuid.uuid4())
386 self.tenant = "tenantname"
387 NSInstModel(id=self.ns_inst_id, name="ns_name").save()
388 NfInstModel.objects.create(nfinstid=self.nf_inst_id, nf_name='name_1', vnf_id='1',
389 vnfm_inst_id='1', ns_inst_id='111,2-2-2',
390 max_cpu='14', max_ram='12296', max_hd='101', max_shd="20", max_net=10,
391 status='active', mnfinstid=self.nf_uuid, package_id='pkg1',
392 vnfd_model='{"metadata": {"vnfdId": "1","vnfdName": "PGW001",'
393 '"vnfProvider": "zte","vnfdVersion": "V00001","vnfVersion": "V5.10.20",'
394 '"productType": "CN","vnfType": "PGW",'
395 '"description": "PGW VNFD description",'
396 '"isShared":true,"vnfExtendType":"driver"}}')
399 NSInstModel.objects.all().delete()
400 NfInstModel.objects.all().delete()
402 def test_scale_vnf(self):
405 "flavour_id": "flavour1",
410 "instances_minimum_number": 1,
411 "instances_maximum_number": 4,
412 "local_affinity_antiaffinity_rule": [
414 "affinity_antiaffinity": "affinity",
423 "name": "demo_aspect",
424 "description": "demo_aspect",
425 "associated_group": "elementGroup1",
431 "group_id": "elementGroup1",
434 "name": "elementGroup1",
436 "members": ["gsu_vm", "pfu_vm"]
444 "aspectId": "demo_aspect1",
446 "additionalParam": vnfd_info
450 "aspectId": "demo_aspect2",
452 "additionalParam": vnfd_info
457 NFManualScaleService(self.nf_inst_id, req_data).run()
458 nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
459 self.assertIsNotNone(nsIns)
461 @mock.patch.object(NFManualScaleService, "send_nf_scaling_request")
462 def test_scale_vnf_success(self, mock_send_nf_scaling_request):
465 "flavour_id": "flavour1",
470 "instances_minimum_number": 1,
471 "instances_maximum_number": 4,
472 "local_affinity_antiaffinity_rule": [
474 "affinity_antiaffinity": "affinity",
483 "name": "demo_aspect",
484 "description": "demo_aspect",
485 "associated_group": "elementGroup1",
491 "group_id": "elementGroup1",
494 "name": "elementGroup1",
496 "members": ["gsu_vm", "pfu_vm"]
504 "aspectId": "demo_aspect1",
506 "additionalParam": vnfd_info
510 "aspectId": "demo_aspect2",
512 "additionalParam": vnfd_info
516 scale_service = NFManualScaleService(self.nf_inst_id, req_data)
518 nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
519 self.assertIsNotNone(nsIns)
521 jobs = JobModel.objects.filter(jobid=scale_service.job_id)
522 self.assertIsNotNone(100, jobs[0].progress)
525 class TestHealVnfViews(TestCase):
527 self.client = Client()
528 self.ns_inst_id = str(uuid.uuid4())
529 self.nf_inst_id = str(uuid.uuid4())
532 self.job_id = JobUtil.create_job("VNF", JOB_TYPE.HEAL_VNF, self.nf_inst_id)
534 NSInstModel(id=self.ns_inst_id, name="ns_name").save()
535 NfInstModel.objects.create(nfinstid=self.nf_inst_id,
539 ns_inst_id='111,2-2-2',
546 mnfinstid=self.nf_uuid,
548 vnfd_model=json.dumps({
551 "vnfdName": "PGW001",
552 "vnfProvider": "zte",
553 "vnfdVersion": "V00001",
554 "vnfVersion": "V5.10.20",
557 "description": "PGW VNFD description",
559 "vnfExtendType": "driver"
564 NSInstModel.objects.all().delete()
565 NfInstModel.objects.all().delete()
567 @mock.patch.object(restcall, "call_req")
568 def test_heal_vnf(self, mock_call_req):
571 "/api/ztevnfmdriver/v1/1/vnfs/111/heal":
572 [0, json.JSONEncoder().encode({"jobId": self.job_id}), '200'],
573 "/external-system/esr-vnfm-list/esr-vnfm/1":
574 [0, json.JSONEncoder().encode(vnfm_info), '200'],
575 "/api/resmgr/v1/vnf/1":
576 [0, json.JSONEncoder().encode({"jobId": self.job_id}), '200'],
577 "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0":
578 [0, json.JSONEncoder().encode({
579 "jobId": self.job_id,
580 "responsedescriptor": {
582 "status": JOB_MODEL_STATUS.FINISHED,
584 "statusdescription": "creating",
586 "responsehistorylist": [{
588 "status": JOB_MODEL_STATUS.PROCESSING,
590 "statusdescription": "creating",
596 def side_effect(*args):
597 return mock_vals[args[4]]
599 mock_call_req.side_effect = side_effect
610 NFHealService(self.nf_inst_id, req_data).run()
612 self.assertEqual(NfInstModel.objects.get(nfinstid=self.nf_inst_id).status, VNF_STATUS.ACTIVE)
614 @mock.patch.object(NFHealService, "run")
615 def test_heal_vnf_non_existing_vnf(self, mock_biz):
616 mock_biz.side_effect = NSLCMException("VNF Not Found")
629 self.assertRaises(NSLCMException, NFHealService(nf_inst_id, req_data).run)
630 self.assertEqual(len(NfInstModel.objects.filter(nfinstid=nf_inst_id)), 0)
633 class TestGetVnfmInfoViews(TestCase):
635 self.client = Client()
636 self.vnfm_id = str(uuid.uuid4())
641 @mock.patch.object(restcall, "call_req")
642 def test_get_vnfm_info(self, mock_call_req):
644 "vnfm-id": "example-vnfm-id-val-62576",
645 "vim-id": "example-vim-id-val-35114",
646 "certificate-url": "example-certificate-url-val-90242",
647 "esr-system-info-list": {
650 "esr-system-info-id": "example-esr-system-info-id-val-78484",
651 "system-name": "example-system-name-val-23790",
652 "type": "example-type-val-52596",
653 "vendor": "example-vendor-val-47399",
654 "version": "example-version-val-42051",
655 "service-url": "example-service-url-val-10731",
656 "user-name": "example-user-name-val-65946",
657 "password": "example-password-val-22505",
658 "system-type": "example-system-type-val-27221",
659 "protocal": "example-protocal-val-54632",
660 "ssl-cacert": "example-ssl-cacert-val-45965",
661 "ssl-insecure": True,
662 "ip-address": "example-ip-address-val-19212",
663 "port": "example-port-val-57641",
664 "cloud-domain": "example-cloud-domain-val-26296",
665 "default-tenant": "example-default-tenant-val-87724"
670 r1 = [0, json.JSONEncoder().encode(vnfm_info_aai), '200']
671 mock_call_req.side_effect = [r1]
672 esr_system_info = ignore_case_get(ignore_case_get(vnfm_info_aai, "esr-system-info-list"), "esr-system-info")
674 "vnfmId": vnfm_info_aai["vnfm-id"],
675 "name": vnfm_info_aai["vnfm-id"],
676 "type": ignore_case_get(esr_system_info[0], "type"),
677 "vimId": vnfm_info_aai["vim-id"],
678 "vendor": ignore_case_get(esr_system_info[0], "vendor"),
679 "version": ignore_case_get(esr_system_info[0], "version"),
680 "description": "vnfm",
681 "certificateUrl": vnfm_info_aai["certificate-url"],
682 "url": ignore_case_get(esr_system_info[0], "service-url"),
683 "userName": ignore_case_get(esr_system_info[0], "user-name"),
684 "password": ignore_case_get(esr_system_info[0], "password"),
688 response = self.client.get("/api/nslcm/v1/vnfms/%s" % self.vnfm_id)
689 self.failUnlessEqual(status.HTTP_200_OK, response.status_code, response.content)
690 context = json.loads(response.content)
691 self.assertEqual(expect_data, context)
694 class TestGetVimInfoViews(TestCase):
696 self.client = Client()
697 self.vim_id = "zte_test"
702 @mock.patch.object(restcall, "call_req")
703 def test_get_vim_info(self, mock_call_req):
704 r1 = [0, json.JSONEncoder().encode(vim_info), '200']
705 mock_call_req.side_effect = [r1]
706 esr_system_info = ignore_case_get(ignore_case_get(vim_info, "esr-system-info-list"), "esr-system-info")
708 "vimId": self.vim_id,
710 "url": ignore_case_get(esr_system_info[0], "service-url"),
711 "userName": ignore_case_get(esr_system_info[0], "user-name"),
712 "password": ignore_case_get(esr_system_info[0], "password"),
713 # "tenant": ignore_case_get(tenants[0], "tenant-id"),
714 "tenant": ignore_case_get(esr_system_info[0], "default-tenant"),
715 "vendor": ignore_case_get(esr_system_info[0], "vendor"),
716 "version": ignore_case_get(esr_system_info[0], "version"),
717 "description": "vim",
719 "type": ignore_case_get(esr_system_info[0], "type"),
723 response = self.client.get("/api/nslcm/v1/vims/%s" % self.vim_id)
724 self.failUnlessEqual(status.HTTP_200_OK, response.status_code)
725 context = json.loads(response.content)
726 self.assertEqual(expect_data["url"], context["url"])
729 class TestPlaceVnfViews(TestCase):
731 self.vnf_inst_id = "1234"
732 self.vnf_inst_name = "vG"
733 self.client = Client()
734 OOFDataModel.objects.all().delete()
735 OOFDataModel.objects.create(
737 transaction_id="1234",
738 request_status="init",
739 request_module_name=self.vnf_inst_name,
740 service_resource_id=self.vnf_inst_id,
748 OOFDataModel.objects.all().delete()
750 @mock.patch.object(restcall, 'call_req')
751 def test_place_vnf(self, mock_call_req):
754 "flavorName": "HPA.flavor.1",
757 PlaceVnfs(vnf_place_request).extract()
758 db_info = OOFDataModel.objects.filter(request_id=vnf_place_request.get("requestId"), transaction_id=vnf_place_request.get("transactionId"))
759 self.assertEqual(db_info[0].request_status, "completed")
760 self.assertEqual(db_info[0].vim_id, "CloudOwner1_DLLSTX1A")
761 self.assertEqual(db_info[0].cloud_owner, "CloudOwner1")
762 self.assertEqual(db_info[0].cloud_region_id, "DLLSTX1A")
763 self.assertEqual(db_info[0].vdu_info, json.dumps(vdu_info_json))
765 def test_place_vnf_with_invalid_response(self):
768 "transactionId": "1234",
769 "statusMessage": "xx",
770 "requestStatus": "pending",
772 "placementSolutions": [
775 "resourceModuleName": self.vnf_inst_name,
776 "serviceResourceId": self.vnf_inst_id,
778 "identifierType": "serviceInstanceId",
782 "cloudOwner": "CloudOwner1 "
788 "licenseSolutions": [
790 "resourceModuleName": "string",
791 "serviceResourceId": "string",
792 "entitlementPoolUUID": [
795 "licenseKeyGroupUUID": [
798 "entitlementPoolInvariantUUID": [
801 "licenseKeyGroupInvariantUUID": [
808 PlaceVnfs(resp).extract()
809 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
810 self.assertEqual(db_info[0].request_status, "pending")
811 self.assertEqual(db_info[0].vim_id, "none")
812 self.assertEqual(db_info[0].cloud_owner, "none")
813 self.assertEqual(db_info[0].cloud_region_id, "none")
814 self.assertEqual(db_info[0].vdu_info, "none")
816 def test_place_vnf_with_no_assignment_info(self):
819 "transactionId": "1234",
820 "statusMessage": "xx",
821 "requestStatus": "completed",
823 "placementSolutions": [
826 "resourceModuleName": self.vnf_inst_name,
827 "serviceResourceId": self.vnf_inst_id,
829 "identifierType": "serviceInstanceId",
833 "cloudOwner": "CloudOwner1 "
838 "licenseSolutions": [
840 "resourceModuleName": "string",
841 "serviceResourceId": "string",
842 "entitlementPoolUUID": [
845 "licenseKeyGroupUUID": [
848 "entitlementPoolInvariantUUID": [
851 "licenseKeyGroupInvariantUUID": [
858 PlaceVnfs(resp).extract()
859 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
860 self.assertEqual(db_info[0].request_status, "completed")
861 self.assertEqual(db_info[0].vim_id, "none")
862 self.assertEqual(db_info[0].cloud_owner, "none")
863 self.assertEqual(db_info[0].cloud_region_id, "none")
864 self.assertEqual(db_info[0].vdu_info, "none")
866 def test_place_vnf_no_directives(self):
869 "transactionId": "1234",
870 "statusMessage": "xx",
871 "requestStatus": "completed",
873 "placementSolutions": [
876 "resourceModuleName": self.vnf_inst_name,
877 "serviceResourceId": self.vnf_inst_id,
879 "identifierType": "serviceInstanceId",
883 "cloudOwner": "CloudOwner1 "
886 {"key": "locationId",
895 "resourceModuleName": "string",
896 "serviceResourceId": "string",
897 "entitlementPoolUUID": [
900 "licenseKeyGroupUUID": [
903 "entitlementPoolInvariantUUID": [
906 "licenseKeyGroupInvariantUUID": [
913 PlaceVnfs(resp).extract()
914 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
915 self.assertEqual(db_info[0].request_status, "completed")
916 self.assertEqual(db_info[0].vim_id, "none")
917 self.assertEqual(db_info[0].cloud_owner, "none")
918 self.assertEqual(db_info[0].cloud_region_id, "none")
919 self.assertEqual(db_info[0].vdu_info, "none")
921 def test_place_vnf_with_no_solution(self):
924 "transactionId": "1234",
925 "statusMessage": "xx",
926 "requestStatus": "completed",
928 "placementSolutions": [],
929 "licenseSoutions": []
932 PlaceVnfs(resp).extract()
933 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
934 self.assertEqual(db_info[0].request_status, "completed")
935 self.assertEqual(db_info[0].vim_id, "none")
936 self.assertEqual(db_info[0].cloud_owner, "none")
937 self.assertEqual(db_info[0].cloud_region_id, "none")
938 self.assertEqual(db_info[0].vdu_info, "none")
941 class TestGrantVnfViews(TestCase):
943 self.vnf_inst_id = str(uuid.uuid4())
945 "vnfInstanceId": self.vnf_inst_id,
946 "vnfLcmOpOccId": "1234",
947 "operation": "INSTANTIATE"
949 vdu_info_dict = [{"vduName": "vg", "flavorName": "flavor_1", "directive": []}]
950 OOFDataModel(request_id='1234', transaction_id='1234', request_status='done', request_module_name='vg',
951 service_resource_id=self.vnf_inst_id, vim_id='cloudOwner_casa', cloud_owner='cloudOwner',
952 cloud_region_id='casa', vdu_info=json.dumps(vdu_info_dict)).save()
955 OOFDataModel.objects.all().delete()
957 @mock.patch.object(resmgr, "grant_vnf")
958 def test_exec_grant(self, mock_grant):
959 resmgr_grant_resp = {
961 "vimId": "cloudOwner_casa",
967 mock_grant.return_value = resmgr_grant_resp
968 resp = GrantVnf(self.data).exec_grant()
969 self.assertEquals(resp['vimAssets']['computeResourceFlavours'][0]['vimConnectionId'], 'cloudOwner_casa')
970 self.assertEquals(resp['vimAssets']['computeResourceFlavours'][0]['resourceProviderId'], 'vg')
971 self.assertEquals(resp['vimAssets']['computeResourceFlavours'][0]['vimFlavourId'], 'flavor_1')
975 'local_storages': [],
988 'vdu_id': u'vdu_omm.001',
989 'image_file': u'opencos_sss_omm_img_release_20150723-1-disk1',
1001 'support_scaling': False,
1004 'storage_policy': '',
1007 'availability_zone': '',
1013 'inject_data_list': [
1020 'local_affinity_antiaffinity_rule': {
1023 'template_id': u'omm.001',
1024 'manual_scale_select_vim': False
1026 'description': u'singleommvm'
1029 'volumn_storages': [
1040 'image_file': u'sss',
1052 'support_scaling': False,
1055 'storage_policy': '',
1058 'availability_zone': '',
1064 'inject_data_list': [
1071 'local_affinity_antiaffinity_rule': {
1074 'template_id': u'1',
1075 'manual_scale_select_vim': False
1077 'description': u'ompvm'
1080 'volumn_storages': [
1091 'image_file': u'sss',
1103 'support_scaling': False,
1106 'storage_policy': '',
1109 'availability_zone': '',
1115 'inject_data_list': [
1122 'local_affinity_antiaffinity_rule': {
1125 'template_id': u'2',
1126 'manual_scale_select_vim': False
1128 'description': u'ompvm'
1131 'volumn_storages': [
1142 'image_file': u'sss',
1154 'support_scaling': False,
1157 'storage_policy': '',
1160 'availability_zone': '',
1166 'inject_data_list': [
1173 'local_affinity_antiaffinity_rule': {
1176 'template_id': u'3',
1177 'manual_scale_select_vim': False
1179 'description': u'ompvm'
1182 'volumn_storages': [
1192 'vdu_id': u'vdu_10',
1193 'image_file': u'sss',
1205 'support_scaling': False,
1208 'storage_policy': '',
1211 'availability_zone': '',
1217 'inject_data_list': [
1224 'local_affinity_antiaffinity_rule': {
1227 'template_id': u'10',
1228 'manual_scale_select_vim': False
1230 'description': u'ppvm'
1233 'volumn_storages': [
1243 'vdu_id': u'vdu_11',
1244 'image_file': u'sss',
1256 'support_scaling': False,
1259 'storage_policy': '',
1262 'availability_zone': '',
1268 'inject_data_list': [
1275 'local_affinity_antiaffinity_rule': {
1278 'template_id': u'11',
1279 'manual_scale_select_vim': False
1281 'description': u'ppvm'
1284 'volumn_storages': [
1294 'vdu_id': u'vdu_12',
1295 'image_file': u'sss',
1307 'support_scaling': False,
1310 'storage_policy': '',
1313 'availability_zone': '',
1319 'inject_data_list': [
1326 'local_affinity_antiaffinity_rule': {
1329 'template_id': u'12',
1330 'manual_scale_select_vim': False
1332 'description': u'ppvm'
1335 'volumn_storages': [
1343 'policy_id': u'policy_scale_sss-vnf-template',
1345 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'
1354 'name': u'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1356 'disk_format': u'VMDK',
1357 'file_url': u'./zte-cn-sss-main-image/OMM/opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1358 'container_type': 'vm',
1360 'hypervisor_type': 'kvm'
1362 'image_file_id': u'opencos_sss_omm_img_release_20150723-1-disk1'
1367 'name': u'sss.vmdk',
1369 'disk_format': u'VMDK',
1370 'file_url': u'./zte-cn-sss-main-image/NE/sss.vmdk',
1371 'container_type': 'vm',
1373 'hypervisor_type': 'kvm'
1375 'image_file_id': u'sss'
1388 'domain_type': u'CN',
1389 'version': u'v4.14.10',
1390 'vmnumber_overquota_alarm': False,
1393 'vnfd_version': u'V00000001',
1394 'id': u'sss-vnf-template',
1395 'name': u'sss-vnf-template'
1404 "externalDataNetworkName": {
1428 "plugin_info": "vbrasplugin_1.0",
1430 "is_shared": "False",
1431 "request_reclassification": "False",
1432 "vnfd_version": "1.0.0",
1434 "nsh_aware": "True",
1435 "cross_dc": "False",
1436 "externalDataNetworkName": {
1437 "get_input": "externalDataNetworkName"
1459 "vl_id": "ext_mnet_network",
1462 "network_type": "vlan",
1463 "name": "externalMNetworkName",
1464 "dhcp_enabled": False,
1472 "end_ip": "190.168.100.100",
1473 "gateway_ip": "190.168.100.1",
1474 "start_ip": "190.168.100.2",
1475 "cidr": "190.168.100.0/24",
1477 "network_name": "sub_mnet",
1489 "invariant_id": "vbras_ns",
1490 "description": "vbras_ns",
1499 "vserver-id": "example-vserver-id-val-70924",
1500 "vserver-name": "example-vserver-name-val-61674",
1501 "vserver-name2": "example-vserver-name2-val-19234",
1502 "prov-status": "example-prov-status-val-94916",
1503 "vserver-selflink": "example-vserver-selflink-val-26562",
1505 "is-closed-loop-disabled": True,
1506 "resource-version": "1505465356263",
1510 "volume-id": "example-volume-id-val-71854",
1511 "volume-selflink": "example-volume-selflink-val-22433"
1518 "interface-name": "example-interface-name-val-24351",
1519 "interface-role": "example-interface-role-val-43242",
1520 "v6-wan-link-ip": "example-v6-wan-link-ip-val-4196",
1521 "selflink": "example-selflink-val-61295",
1522 "interface-id": "example-interface-id-val-95879",
1523 "macaddr": "example-macaddr-val-37302",
1524 "network-name": "example-network-name-val-44254",
1525 "management-option": "example-management-option-val-49009",
1526 "interface-description": "example-interface-description-val-99923",
1527 "is-port-mirrored": True,
1529 "prov-status": "example-prov-status-val-4698",
1530 "is-ip-unnumbered": True,
1531 "allowed-address-pairs": "example-allowed-address-pairs-val-5762",
1535 "vlan-interface": "example-vlan-interface-val-58193",
1536 "vlan-id-inner": 54452151,
1537 "vlan-id-outer": 70239293,
1538 "speed-value": "example-speed-value-val-18677",
1539 "speed-units": "example-speed-units-val-46185",
1540 "vlan-description": "example-vlan-description-val-81675",
1541 "backdoor-connection": "example-backdoor-connection-val-44608",
1542 "vpn-key": "example-vpn-key-val-7946",
1543 "orchestration-status": "example-orchestration-status-val-33611",
1545 "prov-status": "example-prov-status-val-8288",
1546 "is-ip-unnumbered": True,
1547 "l3-interface-ipv4-address-list": [
1549 "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-25520",
1550 "l3-interface-ipv4-prefix-length": 69931928,
1551 "vlan-id-inner": 86628520,
1552 "vlan-id-outer": 62729236,
1553 "is-floating": True,
1554 "neutron-network-id": "example-neutron-network-id-val-64021",
1555 "neutron-subnet-id": "example-neutron-subnet-id-val-95049"
1558 "l3-interface-ipv6-address-list": [
1560 "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-64310",
1561 "l3-interface-ipv6-prefix-length": 57919834,
1562 "vlan-id-inner": 79150122,
1563 "vlan-id-outer": 59789973,
1564 "is-floating": True,
1565 "neutron-network-id": "example-neutron-network-id-val-31713",
1566 "neutron-subnet-id": "example-neutron-subnet-id-val-89568"
1575 "pci-id": "example-pci-id-val-16747",
1576 "vf-vlan-filter": "example-vf-vlan-filter-val-4613",
1577 "vf-mac-filter": "example-vf-mac-filter-val-68168",
1578 "vf-vlan-strip": True,
1579 "vf-vlan-anti-spoof-check": True,
1580 "vf-mac-anti-spoof-check": True,
1581 "vf-mirrors": "example-vf-mirrors-val-6270",
1582 "vf-broadcast-allow": True,
1583 "vf-unknown-multicast-allow": True,
1584 "vf-unknown-unicast-allow": True,
1585 "vf-insert-stag": True,
1586 "vf-link-status": "example-vf-link-status-val-49266",
1587 "neutron-network-id": "example-neutron-network-id-val-29493"
1594 "interface-name": "example-interface-name-val-98222",
1595 "interface-role": "example-interface-role-val-78360",
1596 "v6-wan-link-ip": "example-v6-wan-link-ip-val-76921",
1597 "selflink": "example-selflink-val-27117",
1598 "interface-id": "example-interface-id-val-11260",
1599 "macaddr": "example-macaddr-val-60378",
1600 "network-name": "example-network-name-val-16258",
1601 "management-option": "example-management-option-val-35097",
1602 "interface-description": "example-interface-description-val-10475",
1603 "is-port-mirrored": True,
1605 "prov-status": "example-prov-status-val-65203",
1606 "is-ip-unnumbered": True,
1607 "allowed-address-pairs": "example-allowed-address-pairs-val-65028"
1611 "l3-interface-ipv4-address-list": [
1613 "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-72779",
1614 "l3-interface-ipv4-prefix-length": 55956636,
1615 "vlan-id-inner": 98174431,
1616 "vlan-id-outer": 20372128,
1617 "is-floating": True,
1618 "neutron-network-id": "example-neutron-network-id-val-39596",
1619 "neutron-subnet-id": "example-neutron-subnet-id-val-51109"
1622 "l3-interface-ipv6-address-list": [
1624 "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-95203",
1625 "l3-interface-ipv6-prefix-length": 57454747,
1626 "vlan-id-inner": 53421060,
1627 "vlan-id-outer": 16006050,
1628 "is-floating": True,
1629 "neutron-network-id": "example-neutron-network-id-val-54216",
1630 "neutron-subnet-id": "example-neutron-subnet-id-val-1841"
1640 "vnfm-id": "example-vnfm-id-val-97336",
1641 "vim-id": "zte_test",
1642 "certificate-url": "example-certificate-url-val-18046",
1643 "resource-version": "example-resource-version-val-42094",
1644 "esr-system-info-list": {
1645 "esr-system-info": [
1647 "esr-system-info-id": "example-esr-system-info-id-val-7713",
1648 "system-name": "example-system-name-val-19801",
1649 "type": "ztevnfmdriver",
1650 "vendor": "example-vendor-val-50079",
1651 "version": "example-version-val-93146",
1652 "service-url": "example-service-url-val-68090",
1653 "user-name": "example-user-name-val-14470",
1654 "password": "example-password-val-84190",
1655 "system-type": "example-system-type-val-42773",
1656 "protocal": "example-protocal-val-85736",
1657 "ssl-cacert": "example-ssl-cacert-val-33989",
1658 "ssl-insecure": True,
1659 "ip-address": "example-ip-address-val-99038",
1660 "port": "example-port-val-27323",
1661 "cloud-domain": "example-cloud-domain-val-55163",
1662 "default-tenant": "example-default-tenant-val-99383",
1663 "resource-version": "example-resource-version-val-15424"
1670 "cloud-owner": "example-cloud-owner-val-97336",
1671 "cloud-region-id": "example-cloud-region-id-val-35532",
1672 "cloud-type": "example-cloud-type-val-18046",
1673 "owner-defined-type": "example-owner-defined-type-val-9413",
1674 "cloud-region-version": "example-cloud-region-version-val-85706",
1675 "identity-url": "example-identity-url-val-71252",
1676 "cloud-zone": "example-cloud-zone-val-27112",
1677 "complex-name": "example-complex-name-val-85283",
1678 "sriov-automation": True,
1679 "cloud-extra-info": "example-cloud-extra-info-val-90854",
1680 "cloud-epa-caps": "example-cloud-epa-caps-val-2409",
1681 "resource-version": "example-resource-version-val-42094",
1682 "esr-system-info-list": {
1683 "esr-system-info": [
1685 "esr-system-info-id": "example-esr-system-info-id-val-7713",
1686 "system-name": "example-system-name-val-19801",
1687 "type": "example-type-val-24477",
1688 "vendor": "example-vendor-val-50079",
1689 "version": "example-version-val-93146",
1690 "service-url": "example-service-url-val-68090",
1691 "user-name": "example-user-name-val-14470",
1692 "password": "example-password-val-84190",
1693 "system-type": "example-system-type-val-42773",
1694 "protocal": "example-protocal-val-85736",
1695 "ssl-cacert": "example-ssl-cacert-val-33989",
1696 "ssl-insecure": True,
1697 "ip-address": "example-ip-address-val-99038",
1698 "port": "example-port-val-27323",
1699 "cloud-domain": "example-cloud-domain-val-55163",
1700 "default-tenant": "admin",
1701 "resource-version": "example-resource-version-val-15424"
1708 "csarId": "zte_vbras",
1711 "vnfPackageId": "zte_vbras",
1712 "vnfdProvider": "1",
1716 "vnfdModel": vnfd_model_dict,
1722 vnf_place_request = {
1723 "requestId": "1234",
1724 "transactionId": "1234",
1725 "statusMessage": "xx",
1726 "requestStatus": "completed",
1728 "placementSolutions": [
1731 "resourceModuleName": "vG",
1732 "serviceResourceId": "1234",
1734 "identifierType": "serviceInstanceId",
1738 "cloudOwner": "CloudOwner1"
1744 {"key": "locationId",
1747 {"key": "locationType",
1748 "value": "openstack-cloud"
1751 "value": "CloudOwner1_DLLSTX1A"
1753 {"key": "physicalLocationId",
1754 "value": "DLLSTX1223"
1756 {"key": "oof_directives",
1761 "type": "tocsa.nodes.nfv.Vdu.Compute",
1764 "type": "flavor_directives",
1767 "attribute_name": "flavor_name",
1768 "attribute_value": "HPA.flavor.1"
1781 "attribute_name": " ",
1782 "attribute_value": " "
1795 "licenseSolutions": [
1797 "resourceModuleName": "string",
1798 "serviceResourceId": "string",
1799 "entitlementPoolUUID": [
1802 "licenseKeyGroupUUID": [
1805 "entitlementPoolInvariantUUID": [
1808 "licenseKeyGroupInvariantUUID": [