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.enum import JOB_MODEL_STATUS, JOB_TYPE
25 from lcm.pub.utils.jobutil import JobUtil
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.enum 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.assertEqual(status.HTTP_200_OK, response.status_code)
53 context = json.loads(response.content)
54 self.assertEqual(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",
78 "vimId": '{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}'
84 self.client = Client()
85 NSInstModel(id=self.ns_inst_id, name='ns', nspackage_id='1', nsd_id='nsd_id', description='description',
86 status='instantiating', nsd_model=json.dumps(nsd_model_dict), create_time=now_time(),
87 lastuptime=now_time()).save()
90 NfInstModel.objects.all().delete()
91 JobModel.objects.all().delete()
93 @mock.patch.object(CreateVnfs, 'run')
94 def test_create_vnf(self, mock_run):
95 response = self.client.post("/api/nslcm/v1/ns/vnfs", data=self.data)
96 self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
97 context = json.loads(response.content)
98 self.assertTrue(NfInstModel.objects.filter(nfinstid=context['vnfInstId']).exists())
100 @mock.patch.object(restcall, 'call_req')
101 def test_create_vnf_thread(self, mock_call_req):
102 nf_inst_id, job_id = create_vnfs.prepare_create_params()
104 "/api/ztevnfmdriver/v1/1/vnfs":
105 [0, json.JSONEncoder().encode({"jobId": self.job_id, "vnfInstanceId": 3}), '200'],
106 "/api/catalog/v1/vnfpackages/zte_vbras":
107 [0, json.JSONEncoder().encode(nf_package_info), '200'],
108 "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all":
109 [0, json.JSONEncoder().encode(vnfm_info), '200'],
110 "/api/resmgr/v1/vnf":
111 [0, json.JSONEncoder().encode({}), '200'],
112 "/api/resmgr/v1/vnfinfo":
113 [0, json.JSONEncoder().encode({}), '200'],
114 "/network/generic-vnfs/generic-vnf/%s" % nf_inst_id:
115 [0, json.JSONEncoder().encode({}), '201'],
116 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test?depth=all":
117 [0, json.JSONEncoder().encode(vim_info), '201'],
118 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1":
119 [0, json.JSONEncoder().encode({}), '201'],
120 "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0":
121 [0, json.JSONEncoder().encode({"jobid": self.job_id,
122 "responsedescriptor": {"progress": "100",
123 "status": JOB_MODEL_STATUS.FINISHED,
125 "statusdescription": "creating",
127 "responsehistorylist": [
129 "status": JOB_MODEL_STATUS.PROCESSING,
131 "statusdescription": "creating",
132 "errorcode": "0"}]}}), '200']}
134 def side_effect(*args):
135 return mock_vals[args[4]]
136 mock_call_req.side_effect = side_effect
138 'ns_instance_id': ignore_case_get(self.data, 'nsInstanceId'),
139 'additional_param_for_ns': ignore_case_get(self.data, 'additionalParamForNs'),
140 'additional_param_for_vnf': ignore_case_get(self.data, 'additionalParamForVnf'),
141 'vnf_index': ignore_case_get(self.data, 'vnfIndex')
143 CreateVnfs(data, nf_inst_id, job_id).run()
144 self.assertTrue(NfInstModel.objects.get(nfinstid=nf_inst_id).status, VNF_STATUS.ACTIVE)
146 @mock.patch.object(restcall, 'call_req')
147 @mock.patch.object(CreateVnfs, 'build_homing_request')
148 def test_send_homing_request(self, mock_build_req, mock_call_req):
149 nf_inst_id, job_id = create_vnfs.prepare_create_params()
150 OOFDataModel.objects.all().delete()
153 "transactionId": "1234",
154 "requestStatus": "accepted"
156 mock_build_req.return_value = {
158 "transactionId": "1234",
162 "requestType": "create",
164 "optimizers": ["placement"],
168 "placementDemands": [
170 "resourceModuleName": "vG",
171 "serviceResourceId": "1234",
172 "resourceModelInfo": {
173 "modelInvariantId": "1234",
174 "modelVersionId": "1234"
180 "serviceInstanceId": "1234",
181 "serviceName": "1234",
183 "modelInvariantId": "5678",
184 "modelVersionId": "7890"
188 mock_call_req.return_value = [0, json.JSONEncoder().encode(resp), '202']
190 'ns_instance_id': ignore_case_get(self.data, 'nsInstanceId'),
191 'additional_param_for_ns': ignore_case_get(self.data, 'additionalParamForNs'),
192 'additional_param_for_vnf': ignore_case_get(self.data, 'additionalParamForVnf'),
193 'vnf_index': ignore_case_get(self.data, 'vnfIndex')
195 CreateVnfs(data, nf_inst_id, job_id).send_homing_request_to_OOF()
196 ret = OOFDataModel.objects.filter(request_id="1234", transaction_id="1234")
197 self.assertIsNotNone(ret)
200 class TestTerminateVnfViews(TestCase):
202 self.client = Client()
203 self.ns_inst_id = str(uuid.uuid4())
204 self.nf_inst_id = '1'
205 self.vnffg_id = str(uuid.uuid4())
206 self.vim_id = str(uuid.uuid4())
207 self.job_id = str(uuid.uuid4())
209 self.tenant = "tenantname"
213 "vnfdName": "PGW001",
214 "vnfProvider": "zte",
215 "vnfdVersion": "V00001",
216 "vnfVersion": "V5.10.20",
219 "description": "PGW VNFD description",
221 "vnfExtendType": "driver"
224 NSInstModel.objects.all().delete()
225 NfInstModel.objects.all().delete()
226 VmInstModel.objects.all().delete()
227 NSInstModel(id=self.ns_inst_id, name="ns_name").save()
228 NfInstModel.objects.create(nfinstid=self.nf_inst_id,
232 ns_inst_id='111,2-2-2',
239 mnfinstid=self.nf_uuid,
241 vnfd_model=self.vnfd_model)
242 VmInstModel.objects.create(vmid="1",
244 vimid='{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}',
246 insttype=INST_TYPE.VNF,
247 instid=self.nf_inst_id,
252 NSInstModel.objects.all().delete()
253 NfInstModel.objects.all().delete()
255 @mock.patch.object(TerminateVnfs, 'run')
256 def test_terminate_vnf_url(self, mock_run):
258 "terminationType": "forceful",
259 "gracefulTerminationTimeout": "600"}
261 response = self.client.post("/api/nslcm/v1/ns/terminatevnf/%s" % self.nf_inst_id, data=req_data)
262 self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
264 @mock.patch.object(restcall, 'call_req')
265 @mock.patch.object(SubscriptionDeletion, 'send_subscription_deletion_request')
266 def test_terminate_vnf(self, mock_send_subscription_deletion_request, mock_call_req):
267 job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, self.nf_inst_id)
269 nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
271 self.assertEqual(1, 1)
273 self.assertEqual(1, 0)
275 notification_types = ["VnfLcmOperationOccurrenceNotification"],
296 vnf_instance_subscription_filter = {
298 "vnfInstanceIds": '1',
299 "vnfInstanceNames": [],
300 "vnfProductsFromProviders": {}
302 SubscriptionModel.objects.create(
304 notification_types=json.dumps(notification_types),
305 operation_types=json.dumps(operation_types),
306 operation_states=json.dumps(operation_states),
307 vnf_instance_filter=json.dumps(vnf_instance_subscription_filter),
309 # links=json.dumps(...)
313 "vnf-id": "vnf-id-test111",
314 "vnf-name": "vnf-name-test111",
315 "vnf-type": "vnf-type-test111",
317 "is-closed-loop-disabled": False,
318 "resource-version": "1505465356262"
322 "responsedescriptor": {
324 "status": JOB_MODEL_STATUS.FINISHED,
326 "statusdescription": "creating",
328 "responsehistorylist": [
331 "status": JOB_MODEL_STATUS.PROCESSING,
333 "statusdescription": "creating",
341 "/external-system/esr-vnfm-list/esr-vnfm/1?depth=all":
342 [0, json.JSONEncoder().encode(vnfm_info), '200'],
343 "/api/ztevnfmdriver/v1/1/vnfs/111/terminate":
344 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
345 "/api/resmgr/v1/vnf/1":
346 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
347 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test?depth=all":
348 [0, json.JSONEncoder().encode(vim_info), '201'],
349 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1?depth=all":
350 [0, json.JSONEncoder().encode(vserver_info), '201'],
351 "/cloud-infrastructure/cloud-regions/cloud-region/zte/test/tenants/tenant/admin/vservers/vserver/1?resource-version=1505465356263":
352 [0, json.JSONEncoder().encode({}), '200'],
353 "/api/ztevnfmdriver/v1/1/jobs/" + job_id + "?responseId=0":
354 [0, json.JSONEncoder().encode(job_info), '200'],
355 "/network/generic-vnfs/generic-vnf/1?depth=all":
356 [0, json.JSONEncoder().encode(vnf_info), '200'],
357 "/network/generic-vnfs/generic-vnf/1?resource-version=1505465356262":
358 [0, json.JSONEncoder().encode({}), '200']
361 def side_effect(*args):
362 return mock_vals[args[4]]
364 mock_call_req.side_effect = side_effect
367 "terminationType": "forceful",
368 "gracefulTerminationTimeout": "600"
371 TerminateVnfs(req_data, self.nf_inst_id, job_id).run()
372 nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
374 self.assertEqual(1, 0)
376 self.assertEqual(1, 1)
379 class TestScaleVnfViews(TestCase):
381 self.client = Client()
382 self.ns_inst_id = str(uuid.uuid4())
383 self.nf_inst_id = str(uuid.uuid4())
384 self.vnffg_id = str(uuid.uuid4())
385 self.vim_id = str(uuid.uuid4())
386 self.job_id = str(uuid.uuid4())
388 self.tenant = "tenantname"
389 NSInstModel(id=self.ns_inst_id, name="ns_name").save()
390 NfInstModel.objects.create(nfinstid=self.nf_inst_id, nf_name='name_1', vnf_id='1',
391 vnfm_inst_id='1', ns_inst_id='111,2-2-2',
392 max_cpu='14', max_ram='12296', max_hd='101', max_shd="20", max_net=10,
393 status='active', mnfinstid=self.nf_uuid, package_id='pkg1',
394 vnfd_model='{"metadata": {"vnfdId": "1","vnfdName": "PGW001",'
395 '"vnfProvider": "zte","vnfdVersion": "V00001","vnfVersion": "V5.10.20",'
396 '"productType": "CN","vnfType": "PGW",'
397 '"description": "PGW VNFD description",'
398 '"isShared":true,"vnfExtendType":"driver"}}')
401 NSInstModel.objects.all().delete()
402 NfInstModel.objects.all().delete()
404 def test_scale_vnf(self):
407 "flavour_id": "flavour1",
412 "instances_minimum_number": 1,
413 "instances_maximum_number": 4,
414 "local_affinity_antiaffinity_rule": [
416 "affinity_antiaffinity": "affinity",
425 "name": "demo_aspect",
426 "description": "demo_aspect",
427 "associated_group": "elementGroup1",
433 "group_id": "elementGroup1",
436 "name": "elementGroup1",
438 "members": ["gsu_vm", "pfu_vm"]
446 "aspectId": "demo_aspect1",
448 "additionalParam": vnfd_info
452 "aspectId": "demo_aspect2",
454 "additionalParam": vnfd_info
459 NFManualScaleService(self.nf_inst_id, req_data).run()
460 nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
461 self.assertIsNotNone(nsIns)
463 @mock.patch.object(NFManualScaleService, "send_nf_scaling_request")
464 def test_scale_vnf_success(self, mock_send_nf_scaling_request):
467 "flavour_id": "flavour1",
472 "instances_minimum_number": 1,
473 "instances_maximum_number": 4,
474 "local_affinity_antiaffinity_rule": [
476 "affinity_antiaffinity": "affinity",
485 "name": "demo_aspect",
486 "description": "demo_aspect",
487 "associated_group": "elementGroup1",
493 "group_id": "elementGroup1",
496 "name": "elementGroup1",
498 "members": ["gsu_vm", "pfu_vm"]
506 "aspectId": "demo_aspect1",
508 "additionalParam": vnfd_info
512 "aspectId": "demo_aspect2",
514 "additionalParam": vnfd_info
518 scale_service = NFManualScaleService(self.nf_inst_id, req_data)
520 nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
521 self.assertIsNotNone(nsIns)
523 jobs = JobModel.objects.filter(jobid=scale_service.job_id)
524 self.assertIsNotNone(100, jobs[0].progress)
527 class TestHealVnfViews(TestCase):
529 self.client = Client()
530 self.ns_inst_id = str(uuid.uuid4())
531 self.nf_inst_id = str(uuid.uuid4())
534 self.job_id = JobUtil.create_job("VNF", JOB_TYPE.HEAL_VNF, self.nf_inst_id)
536 NSInstModel(id=self.ns_inst_id, name="ns_name").save()
537 NfInstModel.objects.create(nfinstid=self.nf_inst_id,
541 ns_inst_id='111,2-2-2',
548 mnfinstid=self.nf_uuid,
550 vnfd_model=json.dumps({
553 "vnfdName": "PGW001",
554 "vnfProvider": "zte",
555 "vnfdVersion": "V00001",
556 "vnfVersion": "V5.10.20",
559 "description": "PGW VNFD description",
561 "vnfExtendType": "driver"
566 NSInstModel.objects.all().delete()
567 NfInstModel.objects.all().delete()
569 @mock.patch.object(restcall, "call_req")
570 def test_heal_vnf(self, mock_call_req):
573 "/api/ztevnfmdriver/v1/1/vnfs/111/heal":
574 [0, json.JSONEncoder().encode({"jobId": self.job_id}), '200'],
575 "/external-system/esr-vnfm-list/esr-vnfm/1":
576 [0, json.JSONEncoder().encode(vnfm_info), '200'],
577 "/api/resmgr/v1/vnf/1":
578 [0, json.JSONEncoder().encode({"jobId": self.job_id}), '200'],
579 "/api/ztevnfmdriver/v1/1/jobs/" + self.job_id + "?responseId=0":
580 [0, json.JSONEncoder().encode({
581 "jobId": self.job_id,
582 "responsedescriptor": {
584 "status": JOB_MODEL_STATUS.FINISHED,
586 "statusdescription": "creating",
588 "responsehistorylist": [{
590 "status": JOB_MODEL_STATUS.PROCESSING,
592 "statusdescription": "creating",
598 def side_effect(*args):
599 return mock_vals[args[4]]
601 mock_call_req.side_effect = side_effect
612 NFHealService(self.nf_inst_id, req_data).run()
614 self.assertEqual(NfInstModel.objects.get(nfinstid=self.nf_inst_id).status, VNF_STATUS.ACTIVE)
616 @mock.patch.object(NFHealService, "run")
617 def test_heal_vnf_non_existing_vnf(self, mock_biz):
618 mock_biz.side_effect = NSLCMException("VNF Not Found")
631 self.assertRaises(NSLCMException, NFHealService(nf_inst_id, req_data).run)
632 self.assertEqual(len(NfInstModel.objects.filter(nfinstid=nf_inst_id)), 0)
635 class TestGetVnfmInfoViews(TestCase):
637 self.client = Client()
638 self.vnfm_id = str(uuid.uuid4())
643 @mock.patch.object(restcall, "call_req")
644 def test_get_vnfm_info(self, mock_call_req):
646 "vnfm-id": "example-vnfm-id-val-62576",
647 "vim-id": "example-vim-id-val-35114",
648 "certificate-url": "example-certificate-url-val-90242",
649 "esr-system-info-list": {
652 "esr-system-info-id": "example-esr-system-info-id-val-78484",
653 "system-name": "example-system-name-val-23790",
654 "type": "example-type-val-52596",
655 "vendor": "example-vendor-val-47399",
656 "version": "example-version-val-42051",
657 "service-url": "example-service-url-val-10731",
658 "user-name": "example-user-name-val-65946",
659 "password": "example-password-val-22505",
660 "system-type": "example-system-type-val-27221",
661 "protocal": "example-protocal-val-54632",
662 "ssl-cacert": "example-ssl-cacert-val-45965",
663 "ssl-insecure": True,
664 "ip-address": "example-ip-address-val-19212",
665 "port": "example-port-val-57641",
666 "cloud-domain": "example-cloud-domain-val-26296",
667 "default-tenant": "example-default-tenant-val-87724"
672 r1 = [0, json.JSONEncoder().encode(vnfm_info_aai), '200']
673 mock_call_req.side_effect = [r1]
674 esr_system_info = ignore_case_get(ignore_case_get(vnfm_info_aai, "esr-system-info-list"), "esr-system-info")
676 "vnfmId": vnfm_info_aai["vnfm-id"],
677 "name": vnfm_info_aai["vnfm-id"],
678 "type": ignore_case_get(esr_system_info[0], "type"),
679 "vimId": vnfm_info_aai["vim-id"],
680 "vendor": ignore_case_get(esr_system_info[0], "vendor"),
681 "version": ignore_case_get(esr_system_info[0], "version"),
682 "description": "vnfm",
683 "certificateUrl": vnfm_info_aai["certificate-url"],
684 "url": ignore_case_get(esr_system_info[0], "service-url"),
685 "userName": ignore_case_get(esr_system_info[0], "user-name"),
686 "password": ignore_case_get(esr_system_info[0], "password"),
690 response = self.client.get("/api/nslcm/v1/vnfms/%s" % self.vnfm_id)
691 self.assertEqual(status.HTTP_200_OK, response.status_code, response.content)
692 context = json.loads(response.content)
693 self.assertEqual(expect_data, context)
696 class TestGetVimInfoViews(TestCase):
698 self.client = Client()
699 self.vim_id = {"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}
704 @mock.patch.object(restcall, "call_req")
705 def test_get_vim_info(self, mock_call_req):
706 r1 = [0, json.JSONEncoder().encode(vim_info), '200']
707 mock_call_req.side_effect = [r1]
708 esr_system_info = ignore_case_get(ignore_case_get(vim_info, "esr-system-info-list"), "esr-system-info")
710 "vimId": self.vim_id,
712 "url": ignore_case_get(esr_system_info[0], "service-url"),
713 "userName": ignore_case_get(esr_system_info[0], "user-name"),
714 "password": ignore_case_get(esr_system_info[0], "password"),
715 # "tenant": ignore_case_get(tenants[0], "tenant-id"),
716 "tenant": ignore_case_get(esr_system_info[0], "default-tenant"),
717 "vendor": ignore_case_get(esr_system_info[0], "vendor"),
718 "version": ignore_case_get(esr_system_info[0], "version"),
719 "description": "vim",
721 "type": ignore_case_get(esr_system_info[0], "type"),
725 # response = self.client.get("/api/nslcm/v1/vims/%s" % self.vim_id)
726 response = self.client.get("/api/nslcm/v1/vims/%s/%s" % (self.vim_id['cloud_owner'], self.vim_id['cloud_regionid']))
727 self.assertEqual(status.HTTP_200_OK, response.status_code)
728 context = json.loads(response.content)
729 self.assertEqual(expect_data["url"], context["url"])
732 class TestPlaceVnfViews(TestCase):
734 self.vnf_inst_id = "1234"
736 self.client = Client()
737 OOFDataModel.objects.all().delete()
738 OOFDataModel.objects.create(
740 transaction_id="1234",
741 request_status="init",
742 request_module_name=self.vnf_id,
743 service_resource_id=self.vnf_inst_id,
751 OOFDataModel.objects.all().delete()
753 @mock.patch.object(restcall, 'call_req')
754 def test_place_vnf(self, mock_call_req):
757 "flavorName": "HPA.flavor.1",
761 PlaceVnfs(vnf_place_request).extract()
762 db_info = OOFDataModel.objects.filter(request_id=vnf_place_request.get("requestId"), transaction_id=vnf_place_request.get("transactionId"))
763 self.assertEqual(db_info[0].request_status, "completed")
764 self.assertEqual(db_info[0].vim_id, "CloudOwner1_DLLSTX1A")
765 self.assertEqual(db_info[0].cloud_owner, "CloudOwner1")
766 self.assertEqual(db_info[0].cloud_region_id, "DLLSTX1A")
767 self.assertEqual(db_info[0].vdu_info, json.dumps(vdu_info_json))
769 def test_place_vnf_with_invalid_response(self):
772 "transactionId": "1234",
773 "statusMessage": "xx",
774 "requestStatus": "pending",
776 "placementSolutions": [
779 "resourceModuleName": self.vnf_id,
780 "serviceResourceId": self.vnf_inst_id,
782 "identifierType": "serviceInstanceId",
786 "cloudOwner": "CloudOwner1 "
792 "licenseSolutions": [
794 "resourceModuleName": "string",
795 "serviceResourceId": "string",
796 "entitlementPoolUUID": [
799 "licenseKeyGroupUUID": [
802 "entitlementPoolInvariantUUID": [
805 "licenseKeyGroupInvariantUUID": [
812 PlaceVnfs(resp).extract()
813 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
814 self.assertEqual(db_info[0].request_status, "pending")
815 self.assertEqual(db_info[0].vim_id, "none")
816 self.assertEqual(db_info[0].cloud_owner, "none")
817 self.assertEqual(db_info[0].cloud_region_id, "none")
818 self.assertEqual(db_info[0].vdu_info, "none")
820 def test_place_vnf_with_no_assignment_info(self):
823 "transactionId": "1234",
824 "statusMessage": "xx",
825 "requestStatus": "completed",
827 "placementSolutions": [
830 "resourceModuleName": self.vnf_id,
831 "serviceResourceId": self.vnf_inst_id,
833 "identifierType": "serviceInstanceId",
837 "cloudOwner": "CloudOwner1 "
842 "licenseSolutions": [
844 "resourceModuleName": "string",
845 "serviceResourceId": "string",
846 "entitlementPoolUUID": [
849 "licenseKeyGroupUUID": [
852 "entitlementPoolInvariantUUID": [
855 "licenseKeyGroupInvariantUUID": [
862 PlaceVnfs(resp).extract()
863 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
864 self.assertEqual(db_info[0].request_status, "completed")
865 self.assertEqual(db_info[0].vim_id, "none")
866 self.assertEqual(db_info[0].cloud_owner, "none")
867 self.assertEqual(db_info[0].cloud_region_id, "none")
868 self.assertEqual(db_info[0].vdu_info, "none")
870 def test_place_vnf_no_directives(self):
873 "transactionId": "1234",
874 "statusMessage": "xx",
875 "requestStatus": "completed",
877 "placementSolutions": [
880 "resourceModuleName": self.vnf_id,
881 "serviceResourceId": self.vnf_inst_id,
883 "identifierType": "serviceInstanceId",
887 "cloudOwner": "CloudOwner1 "
890 {"key": "locationId",
899 "resourceModuleName": "string",
900 "serviceResourceId": "string",
901 "entitlementPoolUUID": [
904 "licenseKeyGroupUUID": [
907 "entitlementPoolInvariantUUID": [
910 "licenseKeyGroupInvariantUUID": [
917 PlaceVnfs(resp).extract()
918 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
919 self.assertEqual(db_info[0].request_status, "completed")
920 self.assertEqual(db_info[0].vim_id, "none")
921 self.assertEqual(db_info[0].cloud_owner, "none")
922 self.assertEqual(db_info[0].cloud_region_id, "none")
923 self.assertEqual(db_info[0].vdu_info, "none")
925 def test_place_vnf_with_no_solution(self):
928 "transactionId": "1234",
929 "statusMessage": "xx",
930 "requestStatus": "completed",
932 "placementSolutions": [],
933 "licenseSoutions": []
936 PlaceVnfs(resp).extract()
937 db_info = OOFDataModel.objects.filter(request_id=resp.get("requestId"), transaction_id=resp.get("transactionId"))
938 self.assertEqual(db_info[0].request_status, "completed")
939 self.assertEqual(db_info[0].vim_id, "none")
940 self.assertEqual(db_info[0].cloud_owner, "none")
941 self.assertEqual(db_info[0].cloud_region_id, "none")
942 self.assertEqual(db_info[0].vdu_info, "none")
945 class TestGrantVnfViews(TestCase):
947 self.vnf_inst_id = str(uuid.uuid4())
949 "vnfInstanceId": self.vnf_inst_id,
950 "vnfLcmOpOccId": "1234",
951 "operation": "INSTANTIATE"
953 vdu_info_dict = [{"vduName": "vg", "flavorName": "flavor_1", "flavorId": "12345", "directive": []}]
954 OOFDataModel(request_id='1234', transaction_id='1234', request_status='done', request_module_name='vg',
955 service_resource_id=self.vnf_inst_id, vim_id='cloudOwner_casa', cloud_owner='cloudOwner',
956 cloud_region_id='casa', vdu_info=json.dumps(vdu_info_dict)).save()
959 OOFDataModel.objects.all().delete()
961 @mock.patch.object(resmgr, "grant_vnf")
962 def test_exec_grant(self, mock_grant):
963 resmgr_grant_resp = {
965 "vimId": "cloudOwner_casa",
971 mock_grant.return_value = resmgr_grant_resp
972 resp = GrantVnf(self.data).exec_grant()
973 self.assertEqual(resp['vimAssets']['computeResourceFlavours'][0]['vimConnectionId'], 'cloudOwner_casa')
974 self.assertEqual(resp['vimAssets']['computeResourceFlavours'][0]['resourceProviderId'], 'vg')
975 self.assertEqual(resp['vimAssets']['computeResourceFlavours'][0]['vimFlavourId'], '12345')
979 'local_storages': [],
992 'vdu_id': 'vdu_omm.001',
993 'image_file': 'opencos_sss_omm_img_release_20150723-1-disk1',
1005 'support_scaling': False,
1008 'storage_policy': '',
1011 'availability_zone': '',
1017 'inject_data_list': [
1024 'local_affinity_antiaffinity_rule': {
1027 'template_id': 'omm.001',
1028 'manual_scale_select_vim': False
1030 'description': 'singleommvm'
1033 'volumn_storages': [
1044 'image_file': 'sss',
1056 'support_scaling': False,
1059 'storage_policy': '',
1062 'availability_zone': '',
1068 'inject_data_list': [
1075 'local_affinity_antiaffinity_rule': {
1079 'manual_scale_select_vim': False
1081 'description': 'ompvm'
1084 'volumn_storages': [
1095 'image_file': 'sss',
1107 'support_scaling': False,
1110 'storage_policy': '',
1113 'availability_zone': '',
1119 'inject_data_list': [
1126 'local_affinity_antiaffinity_rule': {
1130 'manual_scale_select_vim': False
1132 'description': 'ompvm'
1135 'volumn_storages': [
1146 'image_file': 'sss',
1158 'support_scaling': False,
1161 'storage_policy': '',
1164 'availability_zone': '',
1170 'inject_data_list': [
1177 'local_affinity_antiaffinity_rule': {
1181 'manual_scale_select_vim': False
1183 'description': 'ompvm'
1186 'volumn_storages': [
1197 'image_file': 'sss',
1209 'support_scaling': False,
1212 'storage_policy': '',
1215 'availability_zone': '',
1221 'inject_data_list': [
1228 'local_affinity_antiaffinity_rule': {
1231 'template_id': '10',
1232 'manual_scale_select_vim': False
1234 'description': 'ppvm'
1237 'volumn_storages': [
1248 'image_file': 'sss',
1260 'support_scaling': False,
1263 'storage_policy': '',
1266 'availability_zone': '',
1272 'inject_data_list': [
1279 'local_affinity_antiaffinity_rule': {
1282 'template_id': '11',
1283 'manual_scale_select_vim': False
1285 'description': 'ppvm'
1288 'volumn_storages': [
1299 'image_file': 'sss',
1311 'support_scaling': False,
1314 'storage_policy': '',
1317 'availability_zone': '',
1323 'inject_data_list': [
1330 'local_affinity_antiaffinity_rule': {
1333 'template_id': '12',
1334 'manual_scale_select_vim': False
1336 'description': 'ppvm'
1339 'volumn_storages': [
1347 'policy_id': 'policy_scale_sss-vnf-template',
1349 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'
1358 'name': 'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1360 'disk_format': 'VMDK',
1361 'file_url': './zte-cn-sss-main-image/OMM/opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1362 'container_type': 'vm',
1364 'hypervisor_type': 'kvm'
1366 'image_file_id': 'opencos_sss_omm_img_release_20150723-1-disk1'
1373 'disk_format': 'VMDK',
1374 'file_url': './zte-cn-sss-main-image/NE/sss.vmdk',
1375 'container_type': 'vm',
1377 'hypervisor_type': 'kvm'
1379 'image_file_id': 'sss'
1392 'domain_type': 'CN',
1393 'version': 'v4.14.10',
1394 'vmnumber_overquota_alarm': False,
1397 'vnfd_version': 'V00000001',
1398 'id': 'sss-vnf-template',
1399 'name': 'sss-vnf-template'
1408 "externalDataNetworkName": {
1432 "plugin_info": "vbrasplugin_1.0",
1434 "is_shared": "False",
1435 "request_reclassification": "False",
1436 "vnfd_version": "1.0.0",
1438 "nsh_aware": "True",
1439 "cross_dc": "False",
1440 "externalDataNetworkName": {
1441 "get_input": "externalDataNetworkName"
1463 "vl_id": "ext_mnet_network",
1466 "network_type": "vlan",
1467 "name": "externalMNetworkName",
1468 "dhcp_enabled": False,
1476 "end_ip": "190.168.100.100",
1477 "gateway_ip": "190.168.100.1",
1478 "start_ip": "190.168.100.2",
1479 "cidr": "190.168.100.0/24",
1481 "network_name": "sub_mnet",
1493 "invariant_id": "vbras_ns",
1494 "description": "vbras_ns",
1503 "vserver-id": "example-vserver-id-val-70924",
1504 "vserver-name": "example-vserver-name-val-61674",
1505 "vserver-name2": "example-vserver-name2-val-19234",
1506 "prov-status": "example-prov-status-val-94916",
1507 "vserver-selflink": "example-vserver-selflink-val-26562",
1509 "is-closed-loop-disabled": True,
1510 "resource-version": "1505465356263",
1514 "volume-id": "example-volume-id-val-71854",
1515 "volume-selflink": "example-volume-selflink-val-22433"
1522 "interface-name": "example-interface-name-val-24351",
1523 "interface-role": "example-interface-role-val-43242",
1524 "v6-wan-link-ip": "example-v6-wan-link-ip-val-4196",
1525 "selflink": "example-selflink-val-61295",
1526 "interface-id": "example-interface-id-val-95879",
1527 "macaddr": "example-macaddr-val-37302",
1528 "network-name": "example-network-name-val-44254",
1529 "management-option": "example-management-option-val-49009",
1530 "interface-description": "example-interface-description-val-99923",
1531 "is-port-mirrored": True,
1533 "prov-status": "example-prov-status-val-4698",
1534 "is-ip-unnumbered": True,
1535 "allowed-address-pairs": "example-allowed-address-pairs-val-5762",
1539 "vlan-interface": "example-vlan-interface-val-58193",
1540 "vlan-id-inner": 54452151,
1541 "vlan-id-outer": 70239293,
1542 "speed-value": "example-speed-value-val-18677",
1543 "speed-units": "example-speed-units-val-46185",
1544 "vlan-description": "example-vlan-description-val-81675",
1545 "backdoor-connection": "example-backdoor-connection-val-44608",
1546 "vpn-key": "example-vpn-key-val-7946",
1547 "orchestration-status": "example-orchestration-status-val-33611",
1549 "prov-status": "example-prov-status-val-8288",
1550 "is-ip-unnumbered": True,
1551 "l3-interface-ipv4-address-list": [
1553 "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-25520",
1554 "l3-interface-ipv4-prefix-length": 69931928,
1555 "vlan-id-inner": 86628520,
1556 "vlan-id-outer": 62729236,
1557 "is-floating": True,
1558 "neutron-network-id": "example-neutron-network-id-val-64021",
1559 "neutron-subnet-id": "example-neutron-subnet-id-val-95049"
1562 "l3-interface-ipv6-address-list": [
1564 "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-64310",
1565 "l3-interface-ipv6-prefix-length": 57919834,
1566 "vlan-id-inner": 79150122,
1567 "vlan-id-outer": 59789973,
1568 "is-floating": True,
1569 "neutron-network-id": "example-neutron-network-id-val-31713",
1570 "neutron-subnet-id": "example-neutron-subnet-id-val-89568"
1579 "pci-id": "example-pci-id-val-16747",
1580 "vf-vlan-filter": "example-vf-vlan-filter-val-4613",
1581 "vf-mac-filter": "example-vf-mac-filter-val-68168",
1582 "vf-vlan-strip": True,
1583 "vf-vlan-anti-spoof-check": True,
1584 "vf-mac-anti-spoof-check": True,
1585 "vf-mirrors": "example-vf-mirrors-val-6270",
1586 "vf-broadcast-allow": True,
1587 "vf-unknown-multicast-allow": True,
1588 "vf-unknown-unicast-allow": True,
1589 "vf-insert-stag": True,
1590 "vf-link-status": "example-vf-link-status-val-49266",
1591 "neutron-network-id": "example-neutron-network-id-val-29493"
1598 "interface-name": "example-interface-name-val-98222",
1599 "interface-role": "example-interface-role-val-78360",
1600 "v6-wan-link-ip": "example-v6-wan-link-ip-val-76921",
1601 "selflink": "example-selflink-val-27117",
1602 "interface-id": "example-interface-id-val-11260",
1603 "macaddr": "example-macaddr-val-60378",
1604 "network-name": "example-network-name-val-16258",
1605 "management-option": "example-management-option-val-35097",
1606 "interface-description": "example-interface-description-val-10475",
1607 "is-port-mirrored": True,
1609 "prov-status": "example-prov-status-val-65203",
1610 "is-ip-unnumbered": True,
1611 "allowed-address-pairs": "example-allowed-address-pairs-val-65028"
1615 "l3-interface-ipv4-address-list": [
1617 "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-72779",
1618 "l3-interface-ipv4-prefix-length": 55956636,
1619 "vlan-id-inner": 98174431,
1620 "vlan-id-outer": 20372128,
1621 "is-floating": True,
1622 "neutron-network-id": "example-neutron-network-id-val-39596",
1623 "neutron-subnet-id": "example-neutron-subnet-id-val-51109"
1626 "l3-interface-ipv6-address-list": [
1628 "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-95203",
1629 "l3-interface-ipv6-prefix-length": 57454747,
1630 "vlan-id-inner": 53421060,
1631 "vlan-id-outer": 16006050,
1632 "is-floating": True,
1633 "neutron-network-id": "example-neutron-network-id-val-54216",
1634 "neutron-subnet-id": "example-neutron-subnet-id-val-1841"
1644 "vnfm-id": "example-vnfm-id-val-97336",
1645 "vim-id": "zte_test",
1646 "certificate-url": "example-certificate-url-val-18046",
1647 "resource-version": "example-resource-version-val-42094",
1648 "esr-system-info-list": {
1649 "esr-system-info": [
1651 "esr-system-info-id": "example-esr-system-info-id-val-7713",
1652 "system-name": "example-system-name-val-19801",
1653 "type": "ztevnfmdriver",
1654 "vendor": "example-vendor-val-50079",
1655 "version": "example-version-val-93146",
1656 "service-url": "example-service-url-val-68090",
1657 "user-name": "example-user-name-val-14470",
1658 "password": "example-password-val-84190",
1659 "system-type": "example-system-type-val-42773",
1660 "protocal": "example-protocal-val-85736",
1661 "ssl-cacert": "example-ssl-cacert-val-33989",
1662 "ssl-insecure": True,
1663 "ip-address": "example-ip-address-val-99038",
1664 "port": "example-port-val-27323",
1665 "cloud-domain": "example-cloud-domain-val-55163",
1666 "default-tenant": "example-default-tenant-val-99383",
1667 "resource-version": "example-resource-version-val-15424"
1674 "cloud-owner": "example-cloud-owner-val-97336",
1675 "cloud-region-id": "example-cloud-region-id-val-35532",
1676 "cloud-type": "example-cloud-type-val-18046",
1677 "owner-defined-type": "example-owner-defined-type-val-9413",
1678 "cloud-region-version": "example-cloud-region-version-val-85706",
1679 "identity-url": "example-identity-url-val-71252",
1680 "cloud-zone": "example-cloud-zone-val-27112",
1681 "complex-name": "example-complex-name-val-85283",
1682 "sriov-automation": True,
1683 "cloud-extra-info": "example-cloud-extra-info-val-90854",
1684 "cloud-epa-caps": "example-cloud-epa-caps-val-2409",
1685 "resource-version": "example-resource-version-val-42094",
1686 "esr-system-info-list": {
1687 "esr-system-info": [
1689 "esr-system-info-id": "example-esr-system-info-id-val-7713",
1690 "system-name": "example-system-name-val-19801",
1691 "type": "example-type-val-24477",
1692 "vendor": "example-vendor-val-50079",
1693 "version": "example-version-val-93146",
1694 "service-url": "example-service-url-val-68090",
1695 "user-name": "example-user-name-val-14470",
1696 "password": "example-password-val-84190",
1697 "system-type": "example-system-type-val-42773",
1698 "protocal": "example-protocal-val-85736",
1699 "ssl-cacert": "example-ssl-cacert-val-33989",
1700 "ssl-insecure": True,
1701 "ip-address": "example-ip-address-val-99038",
1702 "port": "example-port-val-27323",
1703 "cloud-domain": "example-cloud-domain-val-55163",
1704 "default-tenant": "admin",
1705 "resource-version": "example-resource-version-val-15424"
1712 "csarId": "zte_vbras",
1715 "vnfPackageId": "zte_vbras",
1716 "vnfdProvider": "1",
1720 "vnfdModel": vnfd_model_dict,
1726 vnf_place_request = {
1727 "requestId": "1234",
1728 "transactionId": "1234",
1729 "statusMessage": "xx",
1730 "requestStatus": "completed",
1732 "placementSolutions": [
1735 "resourceModuleName": "vG",
1736 "serviceResourceId": "1234",
1738 "identifierType": "serviceInstanceId",
1742 "cloudOwner": "CloudOwner1"
1748 {"key": "locationId",
1751 {"key": "locationType",
1752 "value": "openstack-cloud"
1755 "value": "CloudOwner1_DLLSTX1A"
1757 {"key": "physicalLocationId",
1758 "value": "DLLSTX1223"
1760 {"key": "oof_directives",
1765 "type": "tosca.nodes.nfv.Vdu.Compute",
1768 "type": "flavor_directives",
1771 "attribute_name": "flavorName",
1772 "attribute_value": "HPA.flavor.1"
1775 "attribute_name": "flavorId",
1776 "attribute_value": "12345"
1789 "attribute_name": " ",
1790 "attribute_value": " "
1803 "licenseSolutions": [
1805 "resourceModuleName": "string",
1806 "serviceResourceId": "string",
1807 "entitlementPoolUUID": [
1810 "licenseKeyGroupUUID": [
1813 "entitlementPoolInvariantUUID": [
1816 "licenseKeyGroupInvariantUUID": [