Align gvnfmdriver grant with SOL003
[vfc/nfvo/driver/vnfm/gvnfm.git] / gvnfmadapter / driver / interfaces / tests.py
1 # Copyright 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
15 import json
16 import mock
17 from django.test import Client
18 from django.test import TestCase
19 from rest_framework import status
20 from driver.pub.utils import restcall
21
22
23 class InterfacesTest(TestCase):
24     def setUp(self):
25         self.client = Client()
26
27     def tearDown(self):
28         pass
29
30     @mock.patch.object(restcall, 'call_req')
31     def test_instantiate_vnf(self, mock_call_req):
32         vnfm_info = {
33             'userName': 'admin',
34             'vendor': 'ZTE',
35             'name': 'ZTE_VNFM_237_62',
36             'vimId': '516cee95-e8ca-4d26-9268-38e343c2e31e',
37             'url': 'http: //192.168.237.165: 2324',
38             'certificateUrl': '',
39             'version': 'V1.0',
40             'vnfmId': 'b0797c9b-3da9-459c-b25c-3813e9d8fd70',
41             'password': 'admin',
42             'type': 'gvnfmdriver',
43             'createTime': '2016-10-3111: 08: 39',
44             'description': ''
45         }
46         create_vnf_resp = {
47             "id": "8",
48             # "jobId": "NF-CREATE-8-b384535c-9f45-11e6-8749-fa163e91c2f9"
49         }
50         job_info = {
51             "jobId": "NF-INST-8-6ffa8083-6705-49b3-ae54-cbd6265fbe7a"
52         }
53         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
54         ret = [0, json.JSONEncoder().encode(create_vnf_resp), '200']
55         ret2 = [0, json.JSONEncoder().encode(job_info), '200']
56         mock_call_req.side_effect = [r1, ret, r1, ret2]
57         req_data = {
58             'vnfInstanceName': 'VFW_f88c0cb7-512a-44c4-bd09-891663f19367',
59             'vnfPackageId': 'd852e1be-0aac-48f1-b1a4-cd825f6cdf9a',
60             'vnfDescriptorId': 'vcpe_vfw_zte_1_0',
61             'additionalParam': {
62                 'sdncontroller': 'e4d637f1-a4ec-4c59-8b20-4e8ab34daba9',
63                 'NatIpRange': '192.167.0.10-192.168.0.20',
64                 'm6000_mng_ip': '192.168.11.11',
65                 'externalPluginManageNetworkName': 'plugin_net_2014',
66                 'location': '516cee95-e8ca-4d26-9268-38e343c2e31e',
67                 'externalManageNetworkName': 'mng_net_2017',
68                 'sfc_data_network': 'sfc_data_net_2016',
69                 'externalDataNetworkName': 'Flow_out_net',
70                 'inputs': {}
71             }
72         }
73         response = self.client.post("/api/gvnfmdriver/v1/1/vnfs",
74                                     data=json.dumps(req_data), content_type="application/json")
75         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
76         expect_data = {
77             "vnfInstanceId": "8",
78             "jobId": "NF-INST-8-6ffa8083-6705-49b3-ae54-cbd6265fbe7a"
79         }
80         self.assertEqual(expect_data, response.data)
81
82     @mock.patch.object(restcall, 'call_req')
83     def test_terminate_vnf(self, mock_call_req):
84         vnfm_info = {
85             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
86             "name": "g_vnfm",
87             "type": "gvnfmdriver",
88             "vimId": "",
89             "vendor": "ZTE",
90             "version": "v1.0",
91             "description": "vnfm",
92             "certificateUrl": "",
93             "url": "http://10.74.44.11",
94             "userName": "admin",
95             "password": "admin",
96             "createTime": "2016-07-06 15:33:18"
97         }
98         job_info = {"vnfInstanceId": "1", "vnfLcOpId": "1"}
99         job_status_info = {
100             "jobId": "1",
101             "responseDescriptor": {
102                 "status": "",
103                 "progress": 100,
104                 "statusDescription": "",
105                 "errorCode": "",
106                 "responseId": "2",
107                 "responseHistoryList": [
108                     {
109                         "status": "",
110                         "progress": "",
111                         "statusDescription": "",
112                         "errorCode": "",
113                         "responseId": ""
114                     }
115                 ]
116             }
117         }
118         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
119         r2 = [0, json.JSONEncoder().encode(job_info), "200"]
120         job_ret = [0, json.JSONEncoder().encode(job_status_info), "200"]
121         r3 = [0, json.JSONEncoder().encode(None), "200"]
122         mock_call_req.side_effect = [r1, r2, r1, job_ret, r1, r3]
123         response = self.client.post("/api/gvnfmdriver/v1/ztevnfmid/vnfs/2/terminate")
124         self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code)
125         self.assertEqual(None, response.data)
126
127     @mock.patch.object(restcall, 'call_req')
128     def test_query_vnf(self, mock_call_req):
129         vnfm_info = {
130             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
131             "name": "g_vnfm",
132             "type": "gvnfmdriver",
133             "vimId": "",
134             "vendor": "ZTE",
135             "version": "v1.0",
136             "description": "vnfm",
137             "certificateUrl": "",
138             "url": "http://10.74.44.11",
139             "userName": "admin",
140             "password": "admin",
141             "createTime": "2016-07-06 15:33:18"
142         }
143         job_info = {
144             "ResponseInfo": {
145                 "id": "88",
146                 "instantiationState": "INSTANTIATED",
147                 "vnfSoftwareVersion": "v1.2.3"
148             }
149         }
150         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
151         r2 = [0, json.JSONEncoder().encode(job_info), "200"]
152         mock_call_req.side_effect = [r1, r2]
153         response = self.client.get("/api/gvnfmdriver/v1/19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee/vnfs/88")
154         self.assertEqual(status.HTTP_200_OK, response.status_code)
155         expect_resp_data = {
156             "vnfInfo": {
157                 "vnfInstanceId": "88",
158                 "vnfStatus": "ACTIVE",
159                 "version": "v1.2.3"
160             }
161         }
162         self.assertEqual(expect_resp_data, response.data)
163
164     @mock.patch.object(restcall, 'call_req')
165     def test_operation_status(self, mock_call_req):
166         vnfm_info = {
167             'userName': 'admin',
168             'vendor': 'ZTE',
169             'name': 'ZTE_VNFM_237_62',
170             'vimId': '516cee95-e8ca-4d26-9268-38e343c2e31e',
171             'url': 'http: //192.168.237.165: 2324',
172             'certificateUrl': '',
173             'version': 'V1.0',
174             'vnfmId': 'b0797c9b-3da9-459c-b25c-3813e9d8fd70',
175             'password': 'admin',
176             'type': 'gvnfmdriver',
177             'createTime': '2016-10-3111: 08: 39',
178             'description': ''
179         }
180         expected_body = {
181             "jobId": "NF-CREATE-11-ec6c2f2a-9f48-11e6-9405-fa163e91c2f9",
182             "responseDescriptor": {
183                 "responseId": 3,
184                 "progress": 40,
185                 "status": "PROCESSING",
186                 "statusDescription": "OMC VMs are decommissioned in VIM",
187                 "errorCode": "null",
188                 "responseHistoryList": [
189                     {
190                         "status": "error",
191                         "progress": 255,
192                         "errorcode": "",
193                         "responseid": 20,
194                         "statusdescription": "'JsonParser' object has no attribute 'parser_info'"
195                     }
196                 ]
197             }
198         }
199         resp_body = {
200             "ResponseInfo": {
201                 "vnfLcOpId": "NF-CREATE-11-ec6c2f2a-9f48-11e6-9405-fa163e91c2f9",
202                 "responseDescriptor": {
203                     "responseId": 3,
204                     "progress": 40,
205                     "lcmOperationStatus": "PROCESSING",
206                     "statusDescription": "OMC VMs are decommissioned in VIM",
207                     "errorCode": "null",
208                     "responseHistoryList": [
209                         {
210                             "status": "error",
211                             "progress": 255,
212                             "errorcode": "",
213                             "responseid": 20,
214                             "statusdescription": "'JsonParser' object has no attribute 'parser_info'"
215                         }
216                     ]
217                 }
218             }
219         }
220         r1 = [0, json.JSONEncoder().encode(vnfm_info), '200']
221         r2 = [0, json.JSONEncoder().encode(resp_body), '200']
222         mock_call_req.side_effect = [r1, r2]
223         response = self.client.get("/api/gvnfmdriver/v1/%s/jobs/%s?responseId=0"
224                                    % (vnfm_info["vnfmId"], expected_body["jobId"]))
225         self.assertEqual(status.HTTP_200_OK, response.status_code)
226         self.assertDictEqual(expected_body, response.data)
227
228     @mock.patch.object(restcall, 'call_req')
229     def test_grantvnf(self, mock_call_req):
230         data = {
231             "vnfInstanceId": "1",
232             "vnfLcmOpOccId": "2",
233             "vnfdId": "3",
234             "flavourId": "4",
235             "operation": "INSTANTIATE",
236             "isAutomaticInvocation": True,
237             "instantiationLevelId": "5",
238             "addResources": [
239                 {
240                     "id": "1",
241                     "type": "COMPUTE",
242                     "vduId": "2",
243                     "resourceTemplateId": "3",
244                     "resourceTemplate": {
245                         "vimConnectionId": "4",
246                         "resourceProviderId": "5",
247                         "resourceId": "6",
248                         "vimLevelResourceType": "7"
249                     }
250                 }
251             ],
252             "placementConstraints": [
253                 {
254                     "affinityOrAntiAffinity": "AFFINITY",
255                     "scope": "NFVI_POP",
256                     "resource": [
257                         {
258                             "idType": "RES_MGMT",
259                             "resourceId": "1",
260                             "vimConnectionId": "2",
261                             "resourceProviderId": "3"
262                         }
263                     ]
264                 }
265             ],
266             "vimConstraints": [
267                 {
268                     "sameResourceGroup": True,
269                     "resource": [
270                         {
271                             "idType": "RES_MGMT",
272                             "resourceId": "1",
273                             "vimConnectionId": "2",
274                             "resourceProviderId": "3"
275                         }
276                     ]
277                 }
278             ],
279             "additionalParams": {},
280             "_links": {
281                 "vnfLcmOpOcc": {
282                     "href": "1"
283                 },
284                 "vnfInstance": {
285                     "href": "2"
286                 }
287             }
288         }
289         grant = {
290             'id': 'Identifier of the garnt',
291             'vnfInstanceId': 'Identifier of the related VNF instance',
292             'vnfLcmOpOccId': 'Identifier of the related VNF LcmOpOcc',
293             'vimConnections': [],
294             'zones': [],
295             'zoneGroups': [],
296             'computeReservationId': None,
297             'networkReservationId': None,
298             'storageReservationId': None,
299             'addResources': None,
300             'tempResources': None,
301             'removeResource': None,
302             'updateResource': None,
303             'vimAssets': None,
304             'extVirtualLinks': None,
305             'extManagedVirtualLinks': None,
306             'additionalParams': {},
307             '_links': None
308         }
309
310         mock_call_req.return_value = [0, json.JSONEncoder().encode(grant), '201']
311         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
312                                    data=json.dumps(data), content_type='application/json')
313         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
314         expect_resp_data = {
315             'id': 'Identifier of the garnt',
316             'vnfInstanceId': 'Identifier of the related VNF instance',
317             'vnfLcmOpOccId': 'Identifier of the related VNF LcmOpOcc',
318             'vimConnections': [],
319             'zones': [],
320             'zoneGroups': [],
321             'computeReservationId': None,
322             'networkReservationId': None,
323             'storageReservationId': None,
324             'addResources': None,
325             'tempResources': None,
326             'removeResource': None,
327             'updateResource': None,
328             'vimAssets': None,
329             'extVirtualLinks': None,
330             'extManagedVirtualLinks': None,
331             'additionalParams': {},
332             '_links': None
333         }
334         self.assertDictEqual(expect_resp_data, response.data)
335
336     @mock.patch.object(restcall, 'call_req')
337     def test_grantvnf_failed(self, mock_call_req):
338         data = {
339             "vnfInstanceId": "1",
340             "vnfLcmOpOccId": "2",
341             "vnfdId": "3",
342             "flavourId": "4",
343             "operation": "INSTANTIATE",
344             "isAutomaticInvocation": True,
345             "instantiationLevelId": "5",
346             "addResources": [
347                 {
348                     "id": "1",
349                     "type": "COMPUTE",
350                     "vduId": "2",
351                     "resourceTemplateId": "3",
352                     "resourceTemplate": {
353                         "vimConnectionId": "4",
354                         "resourceProviderId": "5",
355                         "resourceId": "6",
356                         "vimLevelResourceType": "7"
357                     }
358                 }
359             ],
360             "placementConstraints": [
361                 {
362                     "affinityOrAntiAffinity": "AFFINITY",
363                     "scope": "NFVI_POP",
364                     "resource": [
365                         {
366                             "idType": "RES_MGMT",
367                             "resourceId": "1",
368                             "vimConnectionId": "2",
369                             "resourceProviderId": "3"
370                         }
371                     ]
372                 }
373             ],
374             "vimConstraints": [
375                 {
376                     "sameResourceGroup": True,
377                     "resource": [
378                         {
379                             "idType": "RES_MGMT",
380                             "resourceId": "1",
381                             "vimConnectionId": "2",
382                             "resourceProviderId": "3"
383                         }
384                     ]
385                 }
386             ],
387             "additionalParams": {},
388             "_links": {
389                 "vnfLcmOpOcc": {
390                     "href": "1"
391                 },
392                 "vnfInstance": {
393                     "href": "2"
394                 }
395             }
396         }
397         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '201']
398         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
399                                    data=json.dumps(data), content_type='application/json')
400         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code)
401
402     @mock.patch.object(restcall, 'call_req')
403     def test_notify(self, mock_call_req):
404         vim_info = {
405             "vim": {
406                 "vimInfoId": "111111",
407                 "vimId": "12345678",
408                 "interfaceInfo": {
409                     "vimType": "vnf",
410                     "apiVersion": "v1",
411                     "protocolType": "None"
412                 },
413                 "accessInfo": {
414                     "tenant": "tenant1",
415                     "username": "admin",
416                     "password": "password"
417                 },
418                 "interfaceEndpoint": "http://127.0.0.1/api/v1"
419             },
420             "zone": "",
421             "addResource": {
422                 "resourceDefinitionId": "xxxxx",
423                 "vimId": "12345678",
424                 "zoneId": "000"
425             },
426             "removeResource": "",
427             "vimAssets": {
428                 "computeResourceFlavour": {
429                     "vimId": "12345678",
430                     "vduId": "sdfasdf",
431                     "vimFlavourId": "12"
432                 },
433                 "softwareImage": {
434                     "vimId": "12345678",
435                     "imageName": "AAA",
436                     "vimImageId": ""
437                 }
438             },
439             "additionalParam": ""
440         }
441         r2 = [0, json.JSONEncoder().encode(vim_info), "200"]
442         mock_call_req.side_effect = [r2]
443         req_data = {
444             "vnfmInstId": "876543211",
445             "notificationType": "string",
446             "subscriptionId": "string",
447             "timeStamp": "1234567890",
448             "notificationStatus": "START",
449             "operationState": "STARTING",
450             "vnfInstanceId": "string",
451             "operation": "INSTANTIATE",
452             "isAutomaticInvocation": True,
453             "vnfLcmOpOccId": "string",
454             "affectedVnfcs": [{
455                 "id": "string",
456                 "vduId": "string",
457                 "changeType": "ADDED",
458                 "computeResource": {
459                     "vimConnectionId": "string",
460                     "resourceProviderId": "string",
461                     "resourceId": "string",
462                     "vimLevelResourceType": "string"
463                 },
464                 "metadata": {},
465                 "affectedVnfcCpIds": [],
466                 "addedStorageResourceIds": [],
467                 "removedStorageResourceIds": [],
468             }],
469             "affectedVirtualLinks": [{
470                 "id": "string",
471                 "virtualLinkDescId": "string",
472                 "changeType": "ADDED",
473                 "networkResource": {
474                     "vimConnectionId": "string",
475                     "resourceProviderId": "string",
476                     "resourceId": "string",
477                     "vimLevelResourceType": "network",
478                 }
479             }],
480             "affectedVirtualStorages": [{
481                 "id": "string",
482                 "virtualStorageDescId": "string",
483                 "changeType": "ADDED",
484                 "storageResource": {
485                     "vimConnectionId": "string",
486                     "resourceProviderId": "string",
487                     "resourceId": "string",
488                     "vimLevelResourceType": "network",
489                 },
490                 "metadata": {}
491             }],
492             "changedInfo": {
493                 "vnfInstanceName": "string",
494                 "vnfInstanceDescription": "string",
495                 "vnfConfigurableProperties": {},
496                 "metadata": {},
497                 "extensions": {},
498                 "vimConnectionInfo": [{
499                     "id": "string",
500                     "vimId": "string",
501                     "vimType": "string",
502                     "interfaceInfo": {},
503                     "accessInfo": {},
504                     "extra": {}
505                 }],
506                 "vnfPkgId": "string",
507                 "vnfdId": "string",
508                 "vnfProvider": "string",
509                 "vnfProductName": "string",
510                 "vnfSoftwareVersion": "string",
511                 "vnfdVersion": "string"
512             },
513             "changedExtConnectivity": [{
514                 "id": "string",
515                 "resourceHandle": {
516                     "vimConnectionId": "string",
517                     "resourceProviderId": "string",
518                     "resourceId": "string",
519                     "vimLevelResourceType": "string"
520                 },
521                 "extLinkPorts": [{
522                     "id": "string",
523                     "resourceHandle": {
524                         "vimConnectionId": "string",
525                         "resourceProviderId": "string",
526                         "resourceId": "string",
527                         "vimLevelResourceType": "string"
528                     },
529                     "cpInstanceId": "string"
530                 }]
531             }]
532         }
533         response = self.client.post("/api/gvnfmdriver/v1/vnfs/lifecyclechangesnotification",
534                                     data=json.dumps(req_data),
535                                     content_type='application/json')
536         self.assertEqual(status.HTTP_200_OK, response.status_code)
537         expect_resp_data = None
538         self.assertEqual(expect_resp_data, response.data)
539
540     @mock.patch.object(restcall, 'call_req')
541     def test_get_vnfpkgs(self, mock_call_req):
542         vnfpkgs_info = {
543             "csars": [{
544                 "csarId": "1",
545                 "vnfdId": "2"
546             }]
547         }
548         mock_call_req.return_value = [0, json.JSONEncoder().encode(vnfpkgs_info), '200']
549         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
550         self.assertEqual(status.HTTP_200_OK, resp.status_code)
551         self.assertEqual(1, len(resp.data["csars"]))
552         self.assertEqual("1", resp.data["csars"][0]["csarId"])
553         self.assertEqual("2", resp.data["csars"][0]["vnfdId"])
554
555     @mock.patch.object(restcall, 'call_req')
556     def test_get_vnfpkgs_failed(self, mock_call_req):
557         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '200']
558         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
559         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)
560
561     @mock.patch.object(restcall, 'call_req')
562     def test_get_vnflcmopocc_with_id(self, mock_call_req):
563         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
564         vnfm_info = {
565             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
566             "name": "g_vnfm",
567             "type": "gvnfmdriver",
568             "vimId": "",
569             "vendor": "ZTE",
570             "version": "v1.0",
571             "description": "vnfm",
572             "certificateUrl": "",
573             "url": "http://10.74.44.11",
574             "userName": "admin",
575             "password": "admin",
576             "createTime": "2016-07-06 15:33:18"
577         }
578         dummy_single_vnf_lcm_op = {
579             "id": vnfLcmOpOccId,
580             "operationState": "STARTING",
581             "stateEnteredTime": "2018-07-09",
582             "startTime": "2018-07-09",
583             "vnfInstanceId": "cd552c9c-ab6f-11e8-b354-236c32aa91a1",
584             "grantId": None,
585             "operation": "SCALE",
586             "isAutomaticInvocation": False,
587             "operationParams": {},
588             "isCancelPending": False,
589             "cancelMode": None,
590             "error": None,
591             "resourceChanges": None,
592             "changedInfo": None,
593             "changedExtConnectivity": None,
594             "_links": {
595                 "self": {
596                     "href": "dem1o"
597                 },
598                 "vnfInstance": "demo"
599             }
600         }
601         mock_call_req.return_value = [0, json.JSONEncoder().encode(dummy_single_vnf_lcm_op), status.HTTP_200_OK]
602         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
603         self.assertEqual(dummy_single_vnf_lcm_op, resp.data)
604         self.assertEqual(status.HTTP_200_OK, resp.status_code)
605
606     @mock.patch.object(restcall, 'call_req')
607     def test_get_vnflcmopocc_failed(self, mock_call_req):
608         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
609         vnfm_info = {
610             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
611             "name": "g_vnfm",
612             "type": "gvnfmdriver",
613             "vimId": "",
614             "vendor": "ZTE",
615             "version": "v1.0",
616             "description": "vnfm",
617             "certificateUrl": "",
618             "url": "http://10.74.44.11",
619             "userName": "admin",
620             "password": "admin",
621             "createTime": "2016-07-06 15:33:18"
622         }
623         mock_call_req.return_value = [1, json.JSONEncoder().encode({}), status.HTTP_500_INTERNAL_SERVER_ERROR]
624         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
625         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)