8ac7c9629b6bf6a5c02dcce3ef112b59940934fe
[vfc/nfvo/lcm.git] / lcm / ns / tests / vnfs / 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.ns.vnfs import create_vnfs
22 from lcm.ns.vnfs.const import VNF_STATUS
23 from lcm.ns.vnfs.create_vnfs import CreateVnfs
24 from lcm.pub.database.models import NfInstModel, JobModel, NfPackageModel, NSInstModel
25 from lcm.pub.utils import restcall
26 from lcm.pub.utils.jobutil import JOB_MODEL_STATUS
27 from lcm.pub.utils.timeutil import now_time
28 from lcm.pub.utils.values import ignore_case_get
29 from lcm.ns.vnfs.terminate_nfs import TerminateVnfs
30 from lcm.ns.vnfs.scale_vnfs import NFManualScaleService
31 from lcm.pub.utils.jobutil import JobUtil, JOB_TYPE
32
33
34 class TestGetVnfViews(TestCase):
35     def setUp(self):
36         self.client = Client()
37         self.nf_inst_id = str(uuid.uuid4())
38         NfInstModel(nfinstid=self.nf_inst_id, nf_name='vnf1', vnfm_inst_id='1', vnf_id='vnf_id1',
39                     status=VNF_STATUS.ACTIVE, create_time=now_time(), lastuptime=now_time()).save()
40
41     def tearDown(self):
42         NfInstModel.objects.all().delete()
43
44     def test_get_vnf(self):
45         response = self.client.get("/api/nslcm/v1/ns/vnfs/%s" % self.nf_inst_id)
46         self.failUnlessEqual(status.HTTP_200_OK, response.status_code)
47         context = json.loads(response.content)
48         self.failUnlessEqual(self.nf_inst_id, context['vnfInstId'])
49
50
51 class TestCreateVnfViews(TestCase):
52     def setUp(self):
53         self.ns_inst_id = str(uuid.uuid4())
54         self.job_id = str(uuid.uuid4())
55         self.data = {
56             'nsInstanceId': self.ns_inst_id,
57             'additionalParamForNs': {"inputs": json.dumps({})},
58             'additionalParamForVnf': [{
59                 'vnfprofileid': 'VBras',
60                 'additionalparam': {
61                     'inputs': json.dumps({'vnf_param1': '11', 'vnf_param2': '22'}),
62                     'vnfminstanceid': "1"}}],
63             'vnfIndex': '1'}
64         self.client = Client()
65         NfPackageModel(uuid=str(uuid.uuid4()), nfpackageid='package_id1', vnfdid='zte_vbras', vendor='zte',
66                        vnfdversion='1.0.0', vnfversion='1.0.0', vnfdmodel=json.dumps(vnfd_model_dict)).save()
67         NSInstModel(id=self.ns_inst_id, name='ns', nspackage_id='1', nsd_id='nsd_id', description='description',
68                     status='instantiating', nsd_model=json.dumps(nsd_model_dict), create_time=now_time(),
69                     lastuptime=now_time()).save()
70
71     def tearDown(self):
72         NfInstModel.objects.all().delete()
73         JobModel.objects.all().delete()
74
75     @mock.patch.object(CreateVnfs, 'run')
76     def test_create_vnf(self, mock_run):
77         response = self.client.post("/api/nslcm/v1/ns/vnfs", data=self.data)
78         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
79         context = json.loads(response.content)
80         self.assertTrue(NfInstModel.objects.filter(nfinstid=context['vnfInstId']).exists())
81
82     @mock.patch.object(restcall, 'call_req')
83     def test_create_vnf_thread(self, mock_call_req):
84         mock_vals = {
85             "/api/ztevmanagerdriver/v1/1/vnfs":
86                 [0, json.JSONEncoder().encode({"jobId": self.job_id, "vnfInstanceId": 3}), '200'],
87             "/api/extsys/v1/vnfms/1":
88                 [0, json.JSONEncoder().encode({"name": 'vnfm1'}), '200'],
89             "/api/resmgr/v1/vnf":
90                 [0, json.JSONEncoder().encode({}), '200'],
91             "/api/resmgr/v1/vnfinfo":
92                 [0, json.JSONEncoder().encode({}), '200'],
93             "/api/ztevmanagerdriver/v1/jobs/" + self.job_id + "&responseId=0":
94                 [0, json.JSONEncoder().encode({"jobid": self.job_id,
95                                                "responsedescriptor": {"progress": "100",
96                                                                       "status": JOB_MODEL_STATUS.FINISHED,
97                                                                       "responseid": "3",
98                                                                       "statusdescription": "creating",
99                                                                       "errorcode": "0",
100                                                                       "responsehistorylist": [
101                                                                           {"progress": "0",
102                                                                            "status": JOB_MODEL_STATUS.PROCESSING,
103                                                                            "responseid": "2",
104                                                                            "statusdescription": "creating",
105                                                                            "errorcode": "0"}]}}), '200']}
106
107         def side_effect(*args):
108             return mock_vals[args[4]]
109         mock_call_req.side_effect = side_effect
110         data = {'ns_instance_id': ignore_case_get(self.data, 'nsInstanceId'),
111                 'additional_param_for_ns': ignore_case_get(self.data, 'additionalParamForNs'),
112                 'additional_param_for_vnf': ignore_case_get(self.data, 'additionalParamForVnf'),
113                 'vnf_index': ignore_case_get(self.data, 'vnfIndex')}
114         nf_inst_id, job_id = create_vnfs.prepare_create_params()
115         CreateVnfs(data, nf_inst_id, job_id).run()
116         self.assertTrue(NfInstModel.objects.get(nfinstid=nf_inst_id).status, VNF_STATUS.ACTIVE)
117
118
119 class TestTerminateVnfViews(TestCase):
120     def setUp(self):
121         self.client = Client()
122         self.ns_inst_id = str(uuid.uuid4())
123         self.nf_inst_id = '1'
124         self.vnffg_id = str(uuid.uuid4())
125         self.vim_id = str(uuid.uuid4())
126         self.job_id = str(uuid.uuid4())
127         self.nf_uuid = '111'
128         self.tenant = "tenantname"
129         NSInstModel.objects.all().delete()
130         NfInstModel.objects.all().delete()
131         NSInstModel(id=self.ns_inst_id, name="ns_name").save()
132         NfInstModel.objects.create(nfinstid=self.nf_inst_id, nf_name='name_1', vnf_id='1',
133                                    vnfm_inst_id='1', ns_inst_id='111,2-2-2',
134                                    max_cpu='14', max_ram='12296', max_hd='101', max_shd="20", max_net=10,
135                                    status='active', mnfinstid=self.nf_uuid, package_id='pkg1',
136                                    vnfd_model='{"metadata": {"vnfdId": "1","vnfdName": "PGW001",'
137                                               '"vnfProvider": "zte","vnfdVersion": "V00001","vnfVersion": "V5.10.20",'
138                                               '"productType": "CN","vnfType": "PGW",'
139                                               '"description": "PGW VNFD description",'
140                                               '"isShared":true,"vnfExtendType":"driver"}}')
141
142     def tearDown(self):
143         NSInstModel.objects.all().delete()
144         NfInstModel.objects.all().delete()
145
146     @mock.patch.object(TerminateVnfs, 'run')
147     def test_terminate_vnf_url(self, mock_run):
148         req_data = {
149             "terminationType": "forceful",
150             "gracefulTerminationTimeout": "600"}
151
152         response = self.client.post("/api/nslcm/v1/ns/vnfs/%s" % self.nf_inst_id, data=req_data)
153         self.failUnlessEqual(status.HTTP_201_CREATED, response.status_code)
154
155     @mock.patch.object(restcall, "call_req")
156     def test_terminate_vnf(self, mock_call_req):
157         job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, self.nf_inst_id)
158
159         nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
160         if nfinst:
161             self.failUnlessEqual(1, 1)
162         else:
163             self.failUnlessEqual(1, 0)
164
165         mock_vals = {
166             "/api/ztevmanagerdriver/v1/1/vnfs/111/terminate":
167                 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
168             "/api/extsys/v1/vnfms/1":
169                 [0, json.JSONEncoder().encode({"name": 'vnfm1', "type": 'ztevmanagerdriver'}), '200'],
170             "/api/resmgr/v1/vnf/1":
171                 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
172             "/api/ztevmanagerdriver/v1/1/jobs/" + job_id + "?responseId=0":
173                 [0, json.JSONEncoder().encode({"jobId": job_id,
174                                                "responsedescriptor": {"progress": "100",
175                                                                       "status": JOB_MODEL_STATUS.FINISHED,
176                                                                       "responseid": "3",
177                                                                       "statusdescription": "creating",
178                                                                       "errorcode": "0",
179                                                                       "responsehistorylist": [
180                                                                           {"progress": "0",
181                                                                            "status": JOB_MODEL_STATUS.PROCESSING,
182                                                                            "responseid": "2",
183                                                                            "statusdescription": "creating",
184                                                                            "errorcode": "0"}]}}), '200']}
185
186         req_data = {
187             "terminationType": "forceful",
188             "gracefulTerminationTimeout": "600"}
189
190         def side_effect(*args):
191             return mock_vals[args[4]]
192         mock_call_req.side_effect = side_effect
193
194         TerminateVnfs(req_data, self.nf_inst_id, job_id).run()
195         nfinst = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
196         if nfinst:
197             self.failUnlessEqual(1, 0)
198         else:
199             self.failUnlessEqual(1, 1)
200
201 class TestScaleVnfViews(TestCase):
202     def setUp(self):
203         self.client = Client()
204         self.ns_inst_id = str(uuid.uuid4())
205         self.nf_inst_id = str(uuid.uuid4())
206         self.vnffg_id = str(uuid.uuid4())
207         self.vim_id = str(uuid.uuid4())
208         self.job_id = str(uuid.uuid4())
209         self.nf_uuid = '111'
210         self.tenant = "tenantname"
211         NSInstModel(id=self.ns_inst_id, name="ns_name").save()
212         NfInstModel.objects.create(nfinstid=self.nf_inst_id, nf_name='name_1', vnf_id='1',
213                                    vnfm_inst_id='1', ns_inst_id='111,2-2-2',
214                                    max_cpu='14', max_ram='12296', max_hd='101', max_shd="20", max_net=10,
215                                    status='active', mnfinstid=self.nf_uuid, package_id='pkg1',
216                                    vnfd_model='{"metadata": {"vnfdId": "1","vnfdName": "PGW001",'
217                                               '"vnfProvider": "zte","vnfdVersion": "V00001","vnfVersion": "V5.10.20",'
218                                               '"productType": "CN","vnfType": "PGW",'
219                                               '"description": "PGW VNFD description",'
220                                               '"isShared":true,"vnfExtendType":"driver"}}')
221
222     def tearDown(self):
223         NSInstModel.objects.all().delete()
224         NfInstModel.objects.all().delete()
225
226     @mock.patch.object(restcall, "call_req")
227     def test_scale_vnf(self, mock_call_req):
228         job_id = JobUtil.create_job("VNF", JOB_TYPE.TERMINATE_VNF, self.nf_inst_id)
229
230         vnfd_info = {
231             "vnf_flavours":[
232                 {
233                     "flavour_id":"flavour1",
234                     "description":"",
235                     "vdu_profiles":[
236                         {
237                             "vdu_id":"vdu1Id",
238                             "instances_minimum_number": 1,
239                             "instances_maximum_number": 4,
240                             "local_affinity_antiaffinity_rule":[
241                                 {
242                                     "affinity_antiaffinity":"affinity",
243                                     "scope":"node",
244                                 }
245                             ]
246                         }
247                     ],
248                     "scaling_aspects":[
249                         {
250                             "id": "demo_aspect",
251                             "name": "demo_aspect",
252                             "description": "demo_aspect",
253                             "associated_group": "elementGroup1",
254                             "max_scale_level": 5
255                         }
256                     ]
257                 }
258             ],
259             "element_groups": [
260                   {
261                       "group_id": "elementGroup1",
262                       "description": "",
263                       "properties":{
264                           "name": "elementGroup1",
265                       },
266                       "members": ["gsu_vm","pfu_vm"],
267                   }
268             ]
269         }
270
271         req_data = {
272             "scaleVnfData": [
273                 {
274                     "type":"SCALE_OUT",
275                     "aspectId":"demo_aspect1",
276                     "numberOfSteps":1,
277                     "additionalParam":vnfd_info
278                 },
279                 {
280                     "type":"SCALE_OUT",
281                     "aspectId":"demo_aspect2",
282                     "numberOfSteps":1,
283                     "additionalParam":vnfd_info
284                 }
285             ]
286         }
287
288
289         mock_vals = {
290             "/api/ztevmanagerdriver/v1/1/vnfs/111/terminate":
291                 [0, json.JSONEncoder().encode({"jobId": job_id}), '200'],
292             "/api/ztevmanagerdriver/v1/1/vnfs/111/terminate":
293                 [0, json.JSONEncoder().encode({"jobId": job_id}), '200']
294         }
295         NFManualScaleService(self.nf_inst_id, req_data).run()
296         nsIns = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
297         if nsIns:
298             self.failUnlessEqual(1, 1)
299         else:
300             self.failUnlessEqual(1, 0)
301
302 vnfd_model_dict = {
303     'local_storages': [],
304     'vdus': [
305         {
306             'volumn_storages': [],
307             'nfv_compute': {
308                 'mem_size': '',
309                 'num_cpus': u'2'},
310             'local_storages': [],
311             'vdu_id': u'vdu_omm.001',
312             'image_file': u'opencos_sss_omm_img_release_20150723-1-disk1',
313             'dependencies': [],
314             'vls': [],
315             'cps': [],
316             'properties': {
317                 'key_vdu': '',
318                 'support_scaling': False,
319                 'vdu_type': '',
320                 'name': '',
321                 'storage_policy': '',
322                 'location_info': {
323                     'vimId': '',
324                     'availability_zone': '',
325                     'region': '',
326                     'dc': '',
327                     'host': '',
328                     'tenant': ''},
329                 'inject_data_list': [],
330                 'watchdog': {
331                     'action': '',
332                     'enabledelay': ''},
333                 'local_affinity_antiaffinity_rule': {},
334                 'template_id': u'omm.001',
335                 'manual_scale_select_vim': False},
336             'description': u'singleommvm'},
337         {
338             'volumn_storages': [],
339             'nfv_compute': {
340                 'mem_size': '',
341                 'num_cpus': u'4'},
342             'local_storages': [],
343             'vdu_id': u'vdu_1',
344             'image_file': u'sss',
345             'dependencies': [],
346             'vls': [],
347             'cps': [],
348             'properties': {
349                 'key_vdu': '',
350                 'support_scaling': False,
351                 'vdu_type': '',
352                 'name': '',
353                 'storage_policy': '',
354                 'location_info': {
355                     'vimId': '',
356                     'availability_zone': '',
357                     'region': '',
358                     'dc': '',
359                     'host': '',
360                     'tenant': ''},
361                 'inject_data_list': [],
362                 'watchdog': {
363                     'action': '',
364                     'enabledelay': ''},
365                 'local_affinity_antiaffinity_rule': {},
366                 'template_id': u'1',
367                 'manual_scale_select_vim': False},
368             'description': u'ompvm'},
369         {
370             'volumn_storages': [],
371             'nfv_compute': {
372                 'mem_size': '',
373                 'num_cpus': u'14'},
374             'local_storages': [],
375             'vdu_id': u'vdu_2',
376             'image_file': u'sss',
377             'dependencies': [],
378             'vls': [],
379             'cps': [],
380             'properties': {
381                 'key_vdu': '',
382                 'support_scaling': False,
383                 'vdu_type': '',
384                 'name': '',
385                 'storage_policy': '',
386                 'location_info': {
387                     'vimId': '',
388                     'availability_zone': '',
389                     'region': '',
390                     'dc': '',
391                     'host': '',
392                     'tenant': ''},
393                 'inject_data_list': [],
394                 'watchdog': {
395                     'action': '',
396                     'enabledelay': ''},
397                 'local_affinity_antiaffinity_rule': {},
398                 'template_id': u'2',
399                 'manual_scale_select_vim': False},
400             'description': u'ompvm'},
401         {
402             'volumn_storages': [],
403             'nfv_compute': {
404                 'mem_size': '',
405                 'num_cpus': u'14'},
406             'local_storages': [],
407             'vdu_id': u'vdu_3',
408             'image_file': u'sss',
409             'dependencies': [],
410             'vls': [],
411             'cps': [],
412             'properties': {
413                 'key_vdu': '',
414                 'support_scaling': False,
415                 'vdu_type': '',
416                 'name': '',
417                 'storage_policy': '',
418                 'location_info': {
419                     'vimId': '',
420                     'availability_zone': '',
421                     'region': '',
422                     'dc': '',
423                     'host': '',
424                     'tenant': ''},
425                 'inject_data_list': [],
426                 'watchdog': {
427                     'action': '',
428                     'enabledelay': ''},
429                 'local_affinity_antiaffinity_rule': {},
430                 'template_id': u'3',
431                 'manual_scale_select_vim': False},
432             'description': u'ompvm'},
433         {
434             'volumn_storages': [],
435             'nfv_compute': {
436                 'mem_size': '',
437                 'num_cpus': u'4'},
438             'local_storages': [],
439             'vdu_id': u'vdu_10',
440             'image_file': u'sss',
441             'dependencies': [],
442             'vls': [],
443             'cps': [],
444             'properties': {
445                 'key_vdu': '',
446                 'support_scaling': False,
447                 'vdu_type': '',
448                 'name': '',
449                 'storage_policy': '',
450                 'location_info': {
451                     'vimId': '',
452                     'availability_zone': '',
453                     'region': '',
454                     'dc': '',
455                     'host': '',
456                     'tenant': ''},
457                 'inject_data_list': [],
458                 'watchdog': {
459                     'action': '',
460                     'enabledelay': ''},
461                 'local_affinity_antiaffinity_rule': {},
462                 'template_id': u'10',
463                 'manual_scale_select_vim': False},
464             'description': u'ppvm'},
465         {
466             'volumn_storages': [],
467             'nfv_compute': {
468                 'mem_size': '',
469                 'num_cpus': u'14'},
470             'local_storages': [],
471             'vdu_id': u'vdu_11',
472             'image_file': u'sss',
473             'dependencies': [],
474             'vls': [],
475             'cps': [],
476             'properties': {
477                 'key_vdu': '',
478                 'support_scaling': False,
479                 'vdu_type': '',
480                 'name': '',
481                 'storage_policy': '',
482                 'location_info': {
483                     'vimId': '',
484                     'availability_zone': '',
485                     'region': '',
486                     'dc': '',
487                     'host': '',
488                     'tenant': ''},
489                 'inject_data_list': [],
490                 'watchdog': {
491                     'action': '',
492                     'enabledelay': ''},
493                 'local_affinity_antiaffinity_rule': {},
494                 'template_id': u'11',
495                 'manual_scale_select_vim': False},
496             'description': u'ppvm'},
497         {
498             'volumn_storages': [],
499             'nfv_compute': {
500                 'mem_size': '',
501                 'num_cpus': u'14'},
502             'local_storages': [],
503             'vdu_id': u'vdu_12',
504             'image_file': u'sss',
505             'dependencies': [],
506             'vls': [],
507             'cps': [],
508             'properties': {
509                 'key_vdu': '',
510                 'support_scaling': False,
511                 'vdu_type': '',
512                 'name': '',
513                 'storage_policy': '',
514                 'location_info': {
515                     'vimId': '',
516                     'availability_zone': '',
517                     'region': '',
518                     'dc': '',
519                     'host': '',
520                     'tenant': ''},
521                 'inject_data_list': [],
522                 'watchdog': {
523                     'action': '',
524                     'enabledelay': ''},
525                 'local_affinity_antiaffinity_rule': {},
526                 'template_id': u'12',
527                 'manual_scale_select_vim': False},
528             'description': u'ppvm'}],
529     'volumn_storages': [],
530     'policies': {
531         'scaling': {
532             'targets': {},
533             'policy_id': u'policy_scale_sss-vnf-template',
534             'properties': {
535                 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'},
536             'description': ''}},
537     'image_files': [
538         {
539             'description': '',
540             'properties': {
541                 'name': u'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
542                 'checksum': '',
543                 'disk_format': u'VMDK',
544                 'file_url': u'./zte-cn-sss-main-image/OMM/opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
545                 'container_type': 'vm',
546                 'version': '',
547                 'hypervisor_type': 'kvm'},
548             'image_file_id': u'opencos_sss_omm_img_release_20150723-1-disk1'},
549         {
550             'description': '',
551             'properties': {
552                 'name': u'sss.vmdk',
553                 'checksum': '',
554                 'disk_format': u'VMDK',
555                 'file_url': u'./zte-cn-sss-main-image/NE/sss.vmdk',
556                 'container_type': 'vm',
557                 'version': '',
558                 'hypervisor_type': 'kvm'},
559             'image_file_id': u'sss'}],
560     'vls': [],
561     'cps': [],
562     'metadata': {
563         'vendor': u'zte',
564         'is_shared': False,
565         'description': '',
566         'domain_type': u'CN',
567         'version': u'v4.14.10',
568         'vmnumber_overquota_alarm': False,
569         'cross_dc': False,
570         'vnf_type': u'SSS',
571         'vnfd_version': u'V00000001',
572         'id': u'sss-vnf-template',
573         'name': u'sss-vnf-template'}}
574
575 nsd_model_dict = {
576     "vnffgs": [],
577     "inputs": {
578         "externalDataNetworkName": {
579             "default": "",
580             "type": "string",
581             "description": ""}},
582     "pnfs": [],
583     "fps": [],
584     "server_groups": [],
585     "ns_flavours": [],
586     "vnfs": [
587         {
588             "dependency": [],
589             "properties": {
590                 "plugin_info": "vbrasplugin_1.0",
591                 "vendor": "zte",
592                 "is_shared": "False",
593                 "request_reclassification": "False",
594                 "vnfd_version": "1.0.0",
595                 "version": "1.0",
596                 "nsh_aware": "True",
597                 "cross_dc": "False",
598                 "externalDataNetworkName": {
599                     "get_input": "externalDataNetworkName"},
600                 "id": "zte_vbras",
601                 "name": "vbras"},
602             "vnf_id": "VBras",
603             "networks": [],
604             "description": ""}],
605     "ns_exposed": {
606         "external_cps": [],
607         "forward_cps": []},
608     "vls": [
609         {
610             "vl_id": "ext_mnet_network",
611             "description": "",
612             "properties": {
613                 "network_type": "vlan",
614                 "name": "externalMNetworkName",
615                 "dhcp_enabled": False,
616                 "location_info": {
617                     "host": True,
618                     "vimid": 2,
619                     "region": True,
620                     "tenant": "admin",
621                     "dc": ""},
622                 "end_ip": "190.168.100.100",
623                 "gateway_ip": "190.168.100.1",
624                 "start_ip": "190.168.100.2",
625                 "cidr": "190.168.100.0/24",
626                 "mtu": 1500,
627                 "network_name": "sub_mnet",
628                 "ip_version": 4}}],
629     "cps": [],
630     "policies": [],
631     "metadata": {
632         "invariant_id": "vbras_ns",
633         "description": "vbras_ns",
634         "version": 1,
635         "vendor": "zte",
636         "id": "vbras_ns",
637         "name": "vbras_ns"}}