Merge "Refine code for OOF-VFC interaction"
[vfc/nfvo/lcm.git] / lcm / ns_vnfs / tests / tests.py
1 # Copyright 2016-2017 ZTE Corporation.
2 #
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
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14 import json
15 import uuid
16
17 import mock
18 from django.test import TestCase, Client
19 from rest_framework import status
20
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
38
39
40 class TestGetVnfViews(TestCase):
41     def setUp(self):
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()
46
47     def tearDown(self):
48         NfInstModel.objects.all().delete()
49
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'])
55
56
57 class TestCreateVnfViews(TestCase):
58     def setUp(self):
59         self.ns_inst_id = str(uuid.uuid4())
60         self.job_id = str(uuid.uuid4())
61         self.data = {
62             "nsInstanceId": self.ns_inst_id,
63             "additionalParamForNs": {
64                 "inputs": json.dumps({
65
66                 })
67             },
68             "additionalParamForVnf": [
69                 {
70                     "vnfprofileid": "VBras",
71                     "additionalparam": {
72                         "inputs": json.dumps({
73                             "vnf_param1": "11",
74                             "vnf_param2": "22"
75                         }),
76                         "vnfminstanceid": "1",
77                         "vimId": "zte_test"
78                     }
79                 }
80             ],
81             "vnfIndex": "1"
82         }
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()
87
88     def tearDown(self):
89         NfInstModel.objects.all().delete()
90         JobModel.objects.all().delete()
91
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())
98
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()
102         mock_vals = {
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,
123                                                                       "responseid": "3",
124                                                                       "statusdescription": "creating",
125                                                                       "errorcode": "0",
126                                                                       "responsehistorylist": [
127                                                                           {"progress": "0",
128                                                                            "status": JOB_MODEL_STATUS.PROCESSING,
129                                                                            "responseid": "2",
130                                                                            "statusdescription": "creating",
131                                                                            "errorcode": "0"}]}}), '200']}
132
133         def side_effect(*args):
134             return mock_vals[args[4]]
135         mock_call_req.side_effect = side_effect
136         data = {
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')
141         }
142         CreateVnfs(data, nf_inst_id, job_id).run()
143         self.assertTrue(NfInstModel.objects.get(nfinstid=nf_inst_id).status, VNF_STATUS.ACTIVE)
144
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()
150         resp = {
151             "requestId": "1234",
152             "transactionId": "1234",
153             "requestStatus": "accepted"
154         }
155         mock_build_req.return_value = {
156             "requestInfo": {
157                 "transactionId": "1234",
158                 "requestId": "1234",
159                 "callbackUrl": "xx",
160                 "sourceId": "vfc",
161                 "requestType": "create",
162                 "numSolutions": 1,
163                 "optimizers": ["placement"],
164                 "timeout": 600
165             },
166             "placementInfo": {
167                 "placementDemands": [
168                     {
169                         "resourceModuleName": "vG",
170                         "serviceResourceId": "1234",
171                         "resourceModelInfo": {
172                             "modelInvariantId": "1234",
173                             "modelVersionId": "1234"
174                         }
175                     }
176                 ]
177             },
178             "serviceInfo": {
179                 "serviceInstanceId": "1234",
180                 "serviceName": "1234",
181                 "modelInfo": {
182                     "modelInvariantId": "5678",
183                     "modelVersionId": "7890"
184                 }
185             }
186         }
187         mock_call_req.return_value = [0, json.JSONEncoder().encode(resp), '202']
188         data = {
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')
193         }
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)
197
198
199 class TestTerminateVnfViews(TestCase):
200     def setUp(self):
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())
207         self.nf_uuid = '111'
208         self.tenant = "tenantname"
209         self.vnfd_model = {
210             "metadata": {
211                 "vnfdId": "1",
212                 "vnfdName": "PGW001",
213                 "vnfProvider": "zte",
214                 "vnfdVersion": "V00001",
215                 "vnfVersion": "V5.10.20",
216                 "productType": "CN",
217                 "vnfType": "PGW",
218                 "description": "PGW VNFD description",
219                 "isShared": True,
220                 "vnfExtendType": "driver"
221             }
222         }
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,
228                                    nf_name='name_1',
229                                    vnf_id='1',
230                                    vnfm_inst_id='1',
231                                    ns_inst_id='111,2-2-2',
232                                    max_cpu='14',
233                                    max_ram='12296',
234                                    max_hd='101',
235                                    max_shd="20",
236                                    max_net=10,
237                                    status='active',
238                                    mnfinstid=self.nf_uuid,
239                                    package_id='pkg1',
240                                    vnfd_model=self.vnfd_model)
241         VmInstModel.objects.create(vmid="1",
242                                    vimid="zte_test",
243                                    resouceid="1",
244                                    insttype=INST_TYPE.VNF,
245                                    instid=self.nf_inst_id,
246                                    vmname="test",
247                                    hostid='1')
248
249     def tearDown(self):
250         NSInstModel.objects.all().delete()
251         NfInstModel.objects.all().delete()
252
253     @mock.patch.object(TerminateVnfs, 'run')
254     def test_terminate_vnf_url(self, mock_run):
255         req_data = {
256             "terminationType": "forceful",
257             "gracefulTerminationTimeout": "600"}
258
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)
261
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)
266
267         nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
268         if nfinst:
269             self.failUnlessEqual(1, 1)
270         else:
271             self.failUnlessEqual(1, 0)
272
273         notification_types = ["VnfLcmOperationOccurrenceNotification"],
274         operation_types = [
275             "INSTANTIATE",
276             "SCALE",
277             "SCALE_TO_LEVEL",
278             "CHANGE_FLAVOUR",
279             "TERMINATE",
280             "HEAL",
281             "OPERATE",
282             "CHANGE_EXT_CONN",
283             "MODIFY_INFO"
284         ],
285         operation_states = [
286             "STARTING",
287             "PROCESSING",
288             "COMPLETED",
289             "FAILED_TEMP",
290             "FAILED",
291             "ROLLING_BACK",
292             "ROLLED_BACK"
293         ],
294         vnf_instance_subscription_filter = {
295             "vnfdIds": [],
296             "vnfInstanceIds": '1',
297             "vnfInstanceNames": [],
298             "vnfProductsFromProviders": {}
299         }
300         SubscriptionModel.objects.create(
301             subscription_id='1',
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),
306             # callback_uri,
307             # links=json.dumps(...)
308         )
309
310         vnf_info = {
311             "vnf-id": "vnf-id-test111",
312             "vnf-name": "vnf-name-test111",
313             "vnf-type": "vnf-type-test111",
314             "in-maint": True,
315             "is-closed-loop-disabled": False,
316             "resource-version": "1505465356262"
317         }
318         job_info = {
319             "jobId": job_id,
320             "responsedescriptor": {
321                 "progress": "100",
322                 "status": JOB_MODEL_STATUS.FINISHED,
323                 "responseid": "3",
324                 "statusdescription": "creating",
325                 "errorcode": "0",
326                 "responsehistorylist": [
327                     {
328                         "progress": "0",
329                         "status": JOB_MODEL_STATUS.PROCESSING,
330                         "responseid": "2",
331                         "statusdescription": "creating",
332                         "errorcode": "0"
333                     }
334                 ]
335             }
336         }
337
338         mock_vals = {
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']
357         }
358
359         def side_effect(*args):
360             return mock_vals[args[4]]
361
362         mock_call_req.side_effect = side_effect
363
364         req_data = {
365             "terminationType": "forceful",
366             "gracefulTerminationTimeout": "600"
367         }
368
369         TerminateVnfs(req_data, self.nf_inst_id, job_id).run()
370         nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
371         if nfinst:
372             self.failUnlessEqual(1, 0)
373         else:
374             self.failUnlessEqual(1, 1)
375
376
377 class TestScaleVnfViews(TestCase):
378     def setUp(self):
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())
385         self.nf_uuid = '111'
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"}}')
397
398     def tearDown(self):
399         NSInstModel.objects.all().delete()
400         NfInstModel.objects.all().delete()
401
402     def test_scale_vnf(self):
403         vnfd_info = {
404             "vnf_flavours": [{
405                 "flavour_id": "flavour1",
406                 "description": "",
407                 "vdu_profiles": [
408                     {
409                         "vdu_id": "vdu1Id",
410                         "instances_minimum_number": 1,
411                         "instances_maximum_number": 4,
412                         "local_affinity_antiaffinity_rule": [
413                             {
414                                 "affinity_antiaffinity": "affinity",
415                                 "scope": "node",
416                             }
417                         ]
418                     }
419                 ],
420                 "scaling_aspects": [
421                     {
422                         "id": "demo_aspect",
423                         "name": "demo_aspect",
424                         "description": "demo_aspect",
425                         "associated_group": "elementGroup1",
426                         "max_scale_level": 5
427                     }
428                 ]
429             }],
430             "element_groups": [{
431                 "group_id": "elementGroup1",
432                 "description": "",
433                 "properties": {
434                     "name": "elementGroup1",
435                 },
436                 "members": ["gsu_vm", "pfu_vm"]
437             }]
438         }
439
440         req_data = {
441             "scaleVnfData": [
442                 {
443                     "type": "SCALE_OUT",
444                     "aspectId": "demo_aspect1",
445                     "numberOfSteps": 1,
446                     "additionalParam": vnfd_info
447                 },
448                 {
449                     "type": "SCALE_OUT",
450                     "aspectId": "demo_aspect2",
451                     "numberOfSteps": 1,
452                     "additionalParam": vnfd_info
453                 }
454             ]
455         }
456
457         NFManualScaleService(self.nf_inst_id, req_data).run()
458         nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
459         self.assertIsNotNone(nsIns)
460
461     @mock.patch.object(NFManualScaleService, "send_nf_scaling_request")
462     def test_scale_vnf_success(self, mock_send_nf_scaling_request):
463         vnfd_info = {
464             "vnf_flavours": [{
465                 "flavour_id": "flavour1",
466                 "description": "",
467                 "vdu_profiles": [
468                     {
469                         "vdu_id": "vdu1Id",
470                         "instances_minimum_number": 1,
471                         "instances_maximum_number": 4,
472                         "local_affinity_antiaffinity_rule": [
473                             {
474                                 "affinity_antiaffinity": "affinity",
475                                 "scope": "node",
476                             }
477                         ]
478                     }
479                 ],
480                 "scaling_aspects": [
481                     {
482                         "id": "demo_aspect",
483                         "name": "demo_aspect",
484                         "description": "demo_aspect",
485                         "associated_group": "elementGroup1",
486                         "max_scale_level": 5
487                     }
488                 ]
489             }],
490             "element_groups": [{
491                 "group_id": "elementGroup1",
492                 "description": "",
493                 "properties": {
494                     "name": "elementGroup1",
495                 },
496                 "members": ["gsu_vm", "pfu_vm"]
497             }]
498         }
499
500         req_data = {
501             "scaleVnfData": [
502                 {
503                     "type": "SCALE_OUT",
504                     "aspectId": "demo_aspect1",
505                     "numberOfSteps": 1,
506                     "additionalParam": vnfd_info
507                 },
508                 {
509                     "type": "SCALE_OUT",
510                     "aspectId": "demo_aspect2",
511                     "numberOfSteps": 1,
512                     "additionalParam": vnfd_info
513                 }
514             ]
515         }
516         scale_service = NFManualScaleService(self.nf_inst_id, req_data)
517         scale_service.run()
518         nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
519         self.assertIsNotNone(nsIns)
520
521         jobs = JobModel.objects.filter(jobid=scale_service.job_id)
522         self.assertIsNotNone(100, jobs[0].progress)
523
524
525 class TestHealVnfViews(TestCase):
526     def setUp(self):
527         self.client = Client()
528         self.ns_inst_id = str(uuid.uuid4())
529         self.nf_inst_id = str(uuid.uuid4())
530         self.nf_uuid = '111'
531
532         self.job_id = JobUtil.create_job("VNF", JOB_TYPE.HEAL_VNF, self.nf_inst_id)
533
534         NSInstModel(id=self.ns_inst_id, name="ns_name").save()
535         NfInstModel.objects.create(nfinstid=self.nf_inst_id,
536                                    nf_name='name_1',
537                                    vnf_id='1',
538                                    vnfm_inst_id='1',
539                                    ns_inst_id='111,2-2-2',
540                                    max_cpu='14',
541                                    max_ram='12296',
542                                    max_hd='101',
543                                    max_shd="20",
544                                    max_net=10,
545                                    status='active',
546                                    mnfinstid=self.nf_uuid,
547                                    package_id='pkg1',
548                                    vnfd_model=json.dumps({
549                                        "metadata": {
550                                            "vnfdId": "1",
551                                            "vnfdName": "PGW001",
552                                            "vnfProvider": "zte",
553                                            "vnfdVersion": "V00001",
554                                            "vnfVersion": "V5.10.20",
555                                            "productType": "CN",
556                                            "vnfType": "PGW",
557                                            "description": "PGW VNFD description",
558                                            "isShared": True,
559                                            "vnfExtendType": "driver"
560                                        }
561                                    }))
562
563     def tearDown(self):
564         NSInstModel.objects.all().delete()
565         NfInstModel.objects.all().delete()
566
567     @mock.patch.object(restcall, "call_req")
568     def test_heal_vnf(self, mock_call_req):
569
570         mock_vals = {
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": {
581                         "progress": "100",
582                         "status": JOB_MODEL_STATUS.FINISHED,
583                         "responseid": "3",
584                         "statusdescription": "creating",
585                         "errorcode": "0",
586                         "responsehistorylist": [{
587                             "progress": "0",
588                             "status": JOB_MODEL_STATUS.PROCESSING,
589                             "responseid": "2",
590                             "statusdescription": "creating",
591                             "errorcode": "0"
592                         }]
593                     }
594                 }), '200']}
595
596         def side_effect(*args):
597             return mock_vals[args[4]]
598
599         mock_call_req.side_effect = side_effect
600
601         req_data = {
602             "action": "vmReset",
603             "affectedvm": {
604                 "vmid": "1",
605                 "vduid": "1",
606                 "vmname": "name",
607             }
608         }
609
610         NFHealService(self.nf_inst_id, req_data).run()
611
612         self.assertEqual(NfInstModel.objects.get(nfinstid=self.nf_inst_id).status, VNF_STATUS.ACTIVE)
613
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")
617
618         nf_inst_id = "1"
619
620         req_data = {
621             "action": "vmReset",
622             "affectedvm": {
623                 "vmid": "1",
624                 "vduid": "1",
625                 "vmname": "name",
626             }
627         }
628
629         self.assertRaises(NSLCMException, NFHealService(nf_inst_id, req_data).run)
630         self.assertEqual(len(NfInstModel.objects.filter(nfinstid=nf_inst_id)), 0)
631
632
633 class TestGetVnfmInfoViews(TestCase):
634     def setUp(self):
635         self.client = Client()
636         self.vnfm_id = str(uuid.uuid4())
637
638     def tearDown(self):
639         pass
640
641     @mock.patch.object(restcall, "call_req")
642     def test_get_vnfm_info(self, mock_call_req):
643         vnfm_info_aai = {
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": {
648                 "esr-system-info": [
649                     {
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"
666                     }
667                 ]
668             }
669         }
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")
673         expect_data = {
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"),
685             "createTime": ""
686         }
687
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)
692
693
694 class TestGetVimInfoViews(TestCase):
695     def setUp(self):
696         self.client = Client()
697         self.vim_id = "zte_test"
698
699     def tearDown(self):
700         pass
701
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")
707         expect_data = {
708             "vimId": self.vim_id,
709             "name": 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",
718             "domain": "",
719             "type": ignore_case_get(esr_system_info[0], "type"),
720             "createTime": ""
721         }
722
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"])
727
728
729 class TestPlaceVnfViews(TestCase):
730     def setUp(self):
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(
736             request_id="1234",
737             transaction_id="1234",
738             request_status="init",
739             request_module_name=self.vnf_inst_name,
740             service_resource_id=self.vnf_inst_id,
741             vim_id="",
742             cloud_owner="",
743             cloud_region_id="",
744             vdu_info="",
745         )
746
747     def tearDown(self):
748         OOFDataModel.objects.all().delete()
749
750     @mock.patch.object(restcall, 'call_req')
751     def test_place_vnf(self, mock_call_req):
752         vdu_info_json = [{
753             "vduName": "vG_0",
754             "flavorName": "HPA.flavor.1",
755             "directive": []
756         }]
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))
764
765     def test_place_vnf_with_invalid_response(self):
766         resp = {
767             "requestId": "1234",
768             "transactionId": "1234",
769             "statusMessage": "xx",
770             "requestStatus": "pending",
771             "solutions": {
772                 "placementSolutions": [
773                     [
774                         {
775                             "resourceModuleName": self.vnf_inst_name,
776                             "serviceResourceId": self.vnf_inst_id,
777                             "solution": {
778                                 "identifierType": "serviceInstanceId",
779                                 "identifiers": [
780                                     "xx"
781                                 ],
782                                 "cloudOwner": "CloudOwner1 "
783                             },
784                             "assignmentInfo": []
785                         }
786                     ]
787                 ],
788                 "licenseSolutions": [
789                     {
790                         "resourceModuleName": "string",
791                         "serviceResourceId": "string",
792                         "entitlementPoolUUID": [
793                             "string"
794                         ],
795                         "licenseKeyGroupUUID": [
796                             "string"
797                         ],
798                         "entitlementPoolInvariantUUID": [
799                             "string"
800                         ],
801                         "licenseKeyGroupInvariantUUID": [
802                             "string"
803                         ]
804                     }
805                 ]
806             }
807         }
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")
815
816     def test_place_vnf_with_no_assignment_info(self):
817         resp = {
818             "requestId": "1234",
819             "transactionId": "1234",
820             "statusMessage": "xx",
821             "requestStatus": "completed",
822             "solutions": {
823                 "placementSolutions": [
824                     [
825                         {
826                             "resourceModuleName": self.vnf_inst_name,
827                             "serviceResourceId": self.vnf_inst_id,
828                             "solution": {
829                                 "identifierType": "serviceInstanceId",
830                                 "identifiers": [
831                                     "xx"
832                                 ],
833                                 "cloudOwner": "CloudOwner1 "
834                             }
835                         }
836                     ]
837                 ],
838                 "licenseSolutions": [
839                     {
840                         "resourceModuleName": "string",
841                         "serviceResourceId": "string",
842                         "entitlementPoolUUID": [
843                             "string"
844                         ],
845                         "licenseKeyGroupUUID": [
846                             "string"
847                         ],
848                         "entitlementPoolInvariantUUID": [
849                             "string"
850                         ],
851                         "licenseKeyGroupInvariantUUID": [
852                             "string"
853                         ]
854                     }
855                 ]
856             }
857         }
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")
865
866     def test_place_vnf_no_directives(self):
867         resp = {
868             "requestId": "1234",
869             "transactionId": "1234",
870             "statusMessage": "xx",
871             "requestStatus": "completed",
872             "solutions": {
873                 "placementSolutions": [
874                     [
875                         {
876                             "resourceModuleName": self.vnf_inst_name,
877                             "serviceResourceId": self.vnf_inst_id,
878                             "solution": {
879                                 "identifierType": "serviceInstanceId",
880                                 "identifiers": [
881                                     "xx"
882                                 ],
883                                 "cloudOwner": "CloudOwner1 "
884                             },
885                             "assignmentInfo": [
886                                 {"key": "locationId",
887                                  "value": "DLLSTX1A"
888                                  }
889                             ]
890                         }
891                     ]
892                 ],
893                 "licenseSoutions": [
894                     {
895                         "resourceModuleName": "string",
896                         "serviceResourceId": "string",
897                         "entitlementPoolUUID": [
898                             "string"
899                         ],
900                         "licenseKeyGroupUUID": [
901                             "string"
902                         ],
903                         "entitlementPoolInvariantUUID": [
904                             "string"
905                         ],
906                         "licenseKeyGroupInvariantUUID": [
907                             "string"
908                         ]
909                     }
910                 ]
911             }
912         }
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")
920
921     def test_place_vnf_with_no_solution(self):
922         resp = {
923             "requestId": "1234",
924             "transactionId": "1234",
925             "statusMessage": "xx",
926             "requestStatus": "completed",
927             "solutions": {
928                 "placementSolutions": [],
929                 "licenseSoutions": []
930             }
931         }
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")
939
940
941 class TestGrantVnfViews(TestCase):
942     def setUp(self):
943         self.vnf_inst_id = str(uuid.uuid4())
944         self.data = {
945             "vnfInstanceId": self.vnf_inst_id,
946             "vnfLcmOpOccId": "1234",
947             "operation": "INSTANTIATE"
948         }
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()
953
954     def tearDown(self):
955         OOFDataModel.objects.all().delete()
956
957     @mock.patch.object(resmgr, "grant_vnf")
958     def test_exec_grant(self, mock_grant):
959         resmgr_grant_resp = {
960             "vim": {
961                 "vimId": "cloudOwner_casa",
962                 "accessInfo": {
963                     "tenant": "tenantA"
964                 }
965             }
966         }
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')
972
973
974 vnfd_model_dict = {
975     'local_storages': [],
976     'vdus': [
977         {
978             'volumn_storages': [
979
980             ],
981             'nfv_compute': {
982                 'mem_size': '',
983                 'num_cpus': u'2'
984             },
985             'local_storages': [
986
987             ],
988             'vdu_id': u'vdu_omm.001',
989             'image_file': u'opencos_sss_omm_img_release_20150723-1-disk1',
990             'dependencies': [
991
992             ],
993             'vls': [
994
995             ],
996             'cps': [
997
998             ],
999             'properties': {
1000                 'key_vdu': '',
1001                 'support_scaling': False,
1002                 'vdu_type': '',
1003                 'name': '',
1004                 'storage_policy': '',
1005                 'location_info': {
1006                     'vimId': '',
1007                     'availability_zone': '',
1008                     'region': '',
1009                     'dc': '',
1010                     'host': '',
1011                     'tenant': ''
1012                 },
1013                 'inject_data_list': [
1014
1015                 ],
1016                 'watchdog': {
1017                     'action': '',
1018                     'enabledelay': ''
1019                 },
1020                 'local_affinity_antiaffinity_rule': {
1021
1022                 },
1023                 'template_id': u'omm.001',
1024                 'manual_scale_select_vim': False
1025             },
1026             'description': u'singleommvm'
1027         },
1028         {
1029             'volumn_storages': [
1030
1031             ],
1032             'nfv_compute': {
1033                 'mem_size': '',
1034                 'num_cpus': u'4'
1035             },
1036             'local_storages': [
1037
1038             ],
1039             'vdu_id': u'vdu_1',
1040             'image_file': u'sss',
1041             'dependencies': [
1042
1043             ],
1044             'vls': [
1045
1046             ],
1047             'cps': [
1048
1049             ],
1050             'properties': {
1051                 'key_vdu': '',
1052                 'support_scaling': False,
1053                 'vdu_type': '',
1054                 'name': '',
1055                 'storage_policy': '',
1056                 'location_info': {
1057                     'vimId': '',
1058                     'availability_zone': '',
1059                     'region': '',
1060                     'dc': '',
1061                     'host': '',
1062                     'tenant': ''
1063                 },
1064                 'inject_data_list': [
1065
1066                 ],
1067                 'watchdog': {
1068                     'action': '',
1069                     'enabledelay': ''
1070                 },
1071                 'local_affinity_antiaffinity_rule': {
1072
1073                 },
1074                 'template_id': u'1',
1075                 'manual_scale_select_vim': False
1076             },
1077             'description': u'ompvm'
1078         },
1079         {
1080             'volumn_storages': [
1081
1082             ],
1083             'nfv_compute': {
1084                 'mem_size': '',
1085                 'num_cpus': u'14'
1086             },
1087             'local_storages': [
1088
1089             ],
1090             'vdu_id': u'vdu_2',
1091             'image_file': u'sss',
1092             'dependencies': [
1093
1094             ],
1095             'vls': [
1096
1097             ],
1098             'cps': [
1099
1100             ],
1101             'properties': {
1102                 'key_vdu': '',
1103                 'support_scaling': False,
1104                 'vdu_type': '',
1105                 'name': '',
1106                 'storage_policy': '',
1107                 'location_info': {
1108                     'vimId': '',
1109                     'availability_zone': '',
1110                     'region': '',
1111                     'dc': '',
1112                     'host': '',
1113                     'tenant': ''
1114                 },
1115                 'inject_data_list': [
1116
1117                 ],
1118                 'watchdog': {
1119                     'action': '',
1120                     'enabledelay': ''
1121                 },
1122                 'local_affinity_antiaffinity_rule': {
1123
1124                 },
1125                 'template_id': u'2',
1126                 'manual_scale_select_vim': False
1127             },
1128             'description': u'ompvm'
1129         },
1130         {
1131             'volumn_storages': [
1132
1133             ],
1134             'nfv_compute': {
1135                 'mem_size': '',
1136                 'num_cpus': u'14'
1137             },
1138             'local_storages': [
1139
1140             ],
1141             'vdu_id': u'vdu_3',
1142             'image_file': u'sss',
1143             'dependencies': [
1144
1145             ],
1146             'vls': [
1147
1148             ],
1149             'cps': [
1150
1151             ],
1152             'properties': {
1153                 'key_vdu': '',
1154                 'support_scaling': False,
1155                 'vdu_type': '',
1156                 'name': '',
1157                 'storage_policy': '',
1158                 'location_info': {
1159                     'vimId': '',
1160                     'availability_zone': '',
1161                     'region': '',
1162                     'dc': '',
1163                     'host': '',
1164                     'tenant': ''
1165                 },
1166                 'inject_data_list': [
1167
1168                 ],
1169                 'watchdog': {
1170                     'action': '',
1171                     'enabledelay': ''
1172                 },
1173                 'local_affinity_antiaffinity_rule': {
1174
1175                 },
1176                 'template_id': u'3',
1177                 'manual_scale_select_vim': False
1178             },
1179             'description': u'ompvm'
1180         },
1181         {
1182             'volumn_storages': [
1183
1184             ],
1185             'nfv_compute': {
1186                 'mem_size': '',
1187                 'num_cpus': u'4'
1188             },
1189             'local_storages': [
1190
1191             ],
1192             'vdu_id': u'vdu_10',
1193             'image_file': u'sss',
1194             'dependencies': [
1195
1196             ],
1197             'vls': [
1198
1199             ],
1200             'cps': [
1201
1202             ],
1203             'properties': {
1204                 'key_vdu': '',
1205                 'support_scaling': False,
1206                 'vdu_type': '',
1207                 'name': '',
1208                 'storage_policy': '',
1209                 'location_info': {
1210                     'vimId': '',
1211                     'availability_zone': '',
1212                     'region': '',
1213                     'dc': '',
1214                     'host': '',
1215                     'tenant': ''
1216                 },
1217                 'inject_data_list': [
1218
1219                 ],
1220                 'watchdog': {
1221                     'action': '',
1222                     'enabledelay': ''
1223                 },
1224                 'local_affinity_antiaffinity_rule': {
1225
1226                 },
1227                 'template_id': u'10',
1228                 'manual_scale_select_vim': False
1229             },
1230             'description': u'ppvm'
1231         },
1232         {
1233             'volumn_storages': [
1234
1235             ],
1236             'nfv_compute': {
1237                 'mem_size': '',
1238                 'num_cpus': u'14'
1239             },
1240             'local_storages': [
1241
1242             ],
1243             'vdu_id': u'vdu_11',
1244             'image_file': u'sss',
1245             'dependencies': [
1246
1247             ],
1248             'vls': [
1249
1250             ],
1251             'cps': [
1252
1253             ],
1254             'properties': {
1255                 'key_vdu': '',
1256                 'support_scaling': False,
1257                 'vdu_type': '',
1258                 'name': '',
1259                 'storage_policy': '',
1260                 'location_info': {
1261                     'vimId': '',
1262                     'availability_zone': '',
1263                     'region': '',
1264                     'dc': '',
1265                     'host': '',
1266                     'tenant': ''
1267                 },
1268                 'inject_data_list': [
1269
1270                 ],
1271                 'watchdog': {
1272                     'action': '',
1273                     'enabledelay': ''
1274                 },
1275                 'local_affinity_antiaffinity_rule': {
1276
1277                 },
1278                 'template_id': u'11',
1279                 'manual_scale_select_vim': False
1280             },
1281             'description': u'ppvm'
1282         },
1283         {
1284             'volumn_storages': [
1285
1286             ],
1287             'nfv_compute': {
1288                 'mem_size': '',
1289                 'num_cpus': u'14'
1290             },
1291             'local_storages': [
1292
1293             ],
1294             'vdu_id': u'vdu_12',
1295             'image_file': u'sss',
1296             'dependencies': [
1297
1298             ],
1299             'vls': [
1300
1301             ],
1302             'cps': [
1303
1304             ],
1305             'properties': {
1306                 'key_vdu': '',
1307                 'support_scaling': False,
1308                 'vdu_type': '',
1309                 'name': '',
1310                 'storage_policy': '',
1311                 'location_info': {
1312                     'vimId': '',
1313                     'availability_zone': '',
1314                     'region': '',
1315                     'dc': '',
1316                     'host': '',
1317                     'tenant': ''
1318                 },
1319                 'inject_data_list': [
1320
1321                 ],
1322                 'watchdog': {
1323                     'action': '',
1324                     'enabledelay': ''
1325                 },
1326                 'local_affinity_antiaffinity_rule': {
1327
1328                 },
1329                 'template_id': u'12',
1330                 'manual_scale_select_vim': False
1331             },
1332             'description': u'ppvm'
1333         }
1334     ],
1335     'volumn_storages': [
1336
1337     ],
1338     'policies': {
1339         'scaling': {
1340             'targets': {
1341
1342             },
1343             'policy_id': u'policy_scale_sss-vnf-template',
1344             'properties': {
1345                 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'
1346             },
1347             'description': ''
1348         }
1349     },
1350     'image_files': [
1351         {
1352             'description': '',
1353             'properties': {
1354                 'name': u'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1355                 'checksum': '',
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',
1359                 'version': '',
1360                 'hypervisor_type': 'kvm'
1361             },
1362             'image_file_id': u'opencos_sss_omm_img_release_20150723-1-disk1'
1363         },
1364         {
1365             'description': '',
1366             'properties': {
1367                 'name': u'sss.vmdk',
1368                 'checksum': '',
1369                 'disk_format': u'VMDK',
1370                 'file_url': u'./zte-cn-sss-main-image/NE/sss.vmdk',
1371                 'container_type': 'vm',
1372                 'version': '',
1373                 'hypervisor_type': 'kvm'
1374             },
1375             'image_file_id': u'sss'
1376         }
1377     ],
1378     'vls': [
1379
1380     ],
1381     'cps': [
1382
1383     ],
1384     'metadata': {
1385         'vendor': u'zte',
1386         'is_shared': False,
1387         'description': '',
1388         'domain_type': u'CN',
1389         'version': u'v4.14.10',
1390         'vmnumber_overquota_alarm': False,
1391         'cross_dc': False,
1392         'vnf_type': u'SSS',
1393         'vnfd_version': u'V00000001',
1394         'id': u'sss-vnf-template',
1395         'name': u'sss-vnf-template'
1396     }
1397 }
1398
1399 nsd_model_dict = {
1400     "vnffgs": [
1401
1402     ],
1403     "inputs": {
1404         "externalDataNetworkName": {
1405             "default": "",
1406             "type": "string",
1407             "description": ""
1408         }
1409     },
1410     "pnfs": [
1411
1412     ],
1413     "fps": [
1414
1415     ],
1416     "server_groups": [
1417
1418     ],
1419     "ns_flavours": [
1420
1421     ],
1422     "vnfs": [
1423         {
1424             "dependency": [
1425
1426             ],
1427             "properties": {
1428                 "plugin_info": "vbrasplugin_1.0",
1429                 "vendor": "zte",
1430                 "is_shared": "False",
1431                 "request_reclassification": "False",
1432                 "vnfd_version": "1.0.0",
1433                 "version": "1.0",
1434                 "nsh_aware": "True",
1435                 "cross_dc": "False",
1436                 "externalDataNetworkName": {
1437                     "get_input": "externalDataNetworkName"
1438                 },
1439                 "id": "zte_vbras",
1440                 "name": "vbras"
1441             },
1442             "vnf_id": "VBras",
1443             "networks": [
1444
1445             ],
1446             "description": ""
1447         }
1448     ],
1449     "ns_exposed": {
1450         "external_cps": [
1451
1452         ],
1453         "forward_cps": [
1454
1455         ]
1456     },
1457     "vls": [
1458         {
1459             "vl_id": "ext_mnet_network",
1460             "description": "",
1461             "properties": {
1462                 "network_type": "vlan",
1463                 "name": "externalMNetworkName",
1464                 "dhcp_enabled": False,
1465                 "location_info": {
1466                     "host": True,
1467                     "vimid": 2,
1468                     "region": True,
1469                     "tenant": "admin",
1470                     "dc": ""
1471                 },
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",
1476                 "mtu": 1500,
1477                 "network_name": "sub_mnet",
1478                 "ip_version": 4
1479             }
1480         }
1481     ],
1482     "cps": [
1483
1484     ],
1485     "policies": [
1486
1487     ],
1488     "metadata": {
1489         "invariant_id": "vbras_ns",
1490         "description": "vbras_ns",
1491         "version": 1,
1492         "vendor": "zte",
1493         "id": "vbras_ns",
1494         "name": "vbras_ns"
1495     }
1496 }
1497
1498 vserver_info = {
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",
1504     "in-maint": True,
1505     "is-closed-loop-disabled": True,
1506     "resource-version": "1505465356263",
1507     "volumes": {
1508         "volume": [
1509             {
1510                 "volume-id": "example-volume-id-val-71854",
1511                 "volume-selflink": "example-volume-selflink-val-22433"
1512             }
1513         ]
1514     },
1515     "l-interfaces": {
1516         "l-interface": [
1517             {
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,
1528                 "in-maint": True,
1529                 "prov-status": "example-prov-status-val-4698",
1530                 "is-ip-unnumbered": True,
1531                 "allowed-address-pairs": "example-allowed-address-pairs-val-5762",
1532                 "vlans": {
1533                     "vlan": [
1534                         {
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",
1544                             "in-maint": True,
1545                             "prov-status": "example-prov-status-val-8288",
1546                             "is-ip-unnumbered": True,
1547                             "l3-interface-ipv4-address-list": [
1548                                 {
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"
1556                                 }
1557                             ],
1558                             "l3-interface-ipv6-address-list": [
1559                                 {
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"
1567                                 }
1568                             ]
1569                         }
1570                     ]
1571                 },
1572                 "sriov-vfs": {
1573                     "sriov-vf": [
1574                         {
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"
1588                         }
1589                     ]
1590                 },
1591                 "l-interfaces": {
1592                     "l-interface": [
1593                         {
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,
1604                             "in-maint": True,
1605                             "prov-status": "example-prov-status-val-65203",
1606                             "is-ip-unnumbered": True,
1607                             "allowed-address-pairs": "example-allowed-address-pairs-val-65028"
1608                         }
1609                     ]
1610                 },
1611                 "l3-interface-ipv4-address-list": [
1612                     {
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"
1620                     }
1621                 ],
1622                 "l3-interface-ipv6-address-list": [
1623                     {
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"
1631                     }
1632                 ]
1633             }
1634         ]
1635     }
1636 }
1637
1638
1639 vnfm_info = {
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": [
1646             {
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"
1664             }
1665         ]
1666     }
1667 }
1668
1669 vim_info = {
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": [
1684             {
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"
1702             }
1703         ]
1704     }
1705 }
1706
1707 nf_package_info = {
1708     "csarId": "zte_vbras",
1709     "packageInfo": {
1710         "vnfdId": "1",
1711         "vnfPackageId": "zte_vbras",
1712         "vnfdProvider": "1",
1713         "vnfdVersion": "1",
1714         "vnfVersion": "1",
1715         "csarName": "1",
1716         "vnfdModel": vnfd_model_dict,
1717         "downloadUrl": "1"
1718     },
1719     "imageInfo": []
1720 }
1721
1722 vnf_place_request = {
1723     "requestId": "1234",
1724     "transactionId": "1234",
1725     "statusMessage": "xx",
1726     "requestStatus": "completed",
1727     "solutions": {
1728         "placementSolutions": [
1729             [
1730                 {
1731                     "resourceModuleName": "vG",
1732                     "serviceResourceId": "1234",
1733                     "solution": {
1734                         "identifierType": "serviceInstanceId",
1735                         "identifiers": [
1736                             "xx"
1737                         ],
1738                         "cloudOwner": "CloudOwner1"
1739                     },
1740                     "assignmentInfo": [
1741                         {"key": "isRehome",
1742                          "value": "false"
1743                          },
1744                         {"key": "locationId",
1745                          "value": "DLLSTX1A"
1746                          },
1747                         {"key": "locationType",
1748                          "value": "openstack-cloud"
1749                          },
1750                         {"key": "vimId",
1751                          "value": "CloudOwner1_DLLSTX1A"
1752                          },
1753                         {"key": "physicalLocationId",
1754                          "value": "DLLSTX1223"
1755                          },
1756                         {"key": "oof_directives",
1757                          "value": {
1758                              "directives": [
1759                                  {
1760                                      "id": "vG_0",
1761                                      "type": "tocsa.nodes.nfv.Vdu.Compute",
1762                                      "directives": [
1763                                          {
1764                                              "type": "flavor_directives",
1765                                              "attributes": [
1766                                                  {
1767                                                      "attribute_name": "flavor_name",
1768                                                      "attribute_value": "HPA.flavor.1"
1769                                                  }
1770                                              ]
1771                                          }
1772                                      ]
1773                                  },
1774                                  {
1775                                      "id": "",
1776                                      "type": "vnf",
1777                                      "directives": [
1778                                          {"type": " ",
1779                                           "attributes": [
1780                                               {
1781                                                   "attribute_name": " ",
1782                                                   "attribute_value": " "
1783                                               }
1784                                           ]
1785                                           }
1786                                      ]
1787                                  }
1788                              ]
1789                          }
1790                          }
1791                     ]
1792                 }
1793             ]
1794         ],
1795         "licenseSolutions": [
1796             {
1797                 "resourceModuleName": "string",
1798                 "serviceResourceId": "string",
1799                 "entitlementPoolUUID": [
1800                     "string"
1801                 ],
1802                 "licenseKeyGroupUUID": [
1803                     "string"
1804                 ],
1805                 "entitlementPoolInvariantUUID": [
1806                     "string"
1807                 ],
1808                 "licenseKeyGroupInvariantUUID": [
1809                     "string"
1810                 ]
1811             }
1812         ]
1813     }
1814 }