Add Individual VNFLCMOpOcc API to GVNFM Adapter
[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_resp_data = {
290             "id": "1",
291             "vnfInstanceId": "1",
292             "vnfLcmOpOccId": "2",
293             "vimConnections": [
294                 {
295                     "id": "1",
296                     "vimId": "1"
297                 }
298             ]
299         }
300         mock_call_req.return_value = [0, json.JSONEncoder().encode(grant_resp_data), '201']
301         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
302                                    data=json.dumps(data), content_type='application/json')
303         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
304         expect_resp_data = {
305             "id": "1",
306             "vnfInstanceId": "1",
307             "vnfLcmOpOccId": "2",
308             "vimConnections": [
309                 {
310                     "id": "1",
311                     "vimId": "1"
312                 }
313             ]
314         }
315         self.assertDictEqual(expect_resp_data, response.data)
316
317     @mock.patch.object(restcall, 'call_req')
318     def test_grantvnf_failed(self, mock_call_req):
319         data = {
320             "vnfInstanceId": "1",
321             "vnfLcmOpOccId": "2",
322             "vnfdId": "3",
323             "flavourId": "4",
324             "operation": "INSTANTIATE",
325             "isAutomaticInvocation": True,
326             "instantiationLevelId": "5",
327             "addResources": [
328                 {
329                     "id": "1",
330                     "type": "COMPUTE",
331                     "vduId": "2",
332                     "resourceTemplateId": "3",
333                     "resourceTemplate": {
334                         "vimConnectionId": "4",
335                         "resourceProviderId": "5",
336                         "resourceId": "6",
337                         "vimLevelResourceType": "7"
338                     }
339                 }
340             ],
341             "placementConstraints": [
342                 {
343                     "affinityOrAntiAffinity": "AFFINITY",
344                     "scope": "NFVI_POP",
345                     "resource": [
346                         {
347                             "idType": "RES_MGMT",
348                             "resourceId": "1",
349                             "vimConnectionId": "2",
350                             "resourceProviderId": "3"
351                         }
352                     ]
353                 }
354             ],
355             "vimConstraints": [
356                 {
357                     "sameResourceGroup": True,
358                     "resource": [
359                         {
360                             "idType": "RES_MGMT",
361                             "resourceId": "1",
362                             "vimConnectionId": "2",
363                             "resourceProviderId": "3"
364                         }
365                     ]
366                 }
367             ],
368             "additionalParams": {},
369             "_links": {
370                 "vnfLcmOpOcc": {
371                     "href": "1"
372                 },
373                 "vnfInstance": {
374                     "href": "2"
375                 }
376             }
377         }
378         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '201']
379         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
380                                    data=json.dumps(data), content_type='application/json')
381         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code)
382
383     @mock.patch.object(restcall, 'call_req')
384     def test_notify(self, mock_call_req):
385         vim_info = {
386             "vim": {
387                 "vimInfoId": "111111",
388                 "vimId": "12345678",
389                 "interfaceInfo": {
390                     "vimType": "vnf",
391                     "apiVersion": "v1",
392                     "protocolType": "None"
393                 },
394                 "accessInfo": {
395                     "tenant": "tenant1",
396                     "username": "admin",
397                     "password": "password"
398                 },
399                 "interfaceEndpoint": "http://127.0.0.1/api/v1"
400             },
401             "zone": "",
402             "addResource": {
403                 "resourceDefinitionId": "xxxxx",
404                 "vimId": "12345678",
405                 "zoneId": "000"
406             },
407             "removeResource": "",
408             "vimAssets": {
409                 "computeResourceFlavour": {
410                     "vimId": "12345678",
411                     "vduId": "sdfasdf",
412                     "vimFlavourId": "12"
413                 },
414                 "softwareImage": {
415                     "vimId": "12345678",
416                     "imageName": "AAA",
417                     "vimImageId": ""
418                 }
419             },
420             "additionalParam": ""
421         }
422         r2 = [0, json.JSONEncoder().encode(vim_info), "200"]
423         mock_call_req.side_effect = [r2]
424         req_data = {
425             "vnfmInstId": "876543211",
426             "notificationType": "string",
427             "subscriptionId": "string",
428             "timeStamp": "1234567890",
429             "notificationStatus": "START",
430             "operationState": "STARTING",
431             "vnfInstanceId": "string",
432             "operation": "INSTANTIATE",
433             "isAutomaticInvocation": True,
434             "vnfLcmOpOccId": "string",
435             "affectedVnfcs": [{
436                 "id": "string",
437                 "vduId": "string",
438                 "changeType": "ADDED",
439                 "computeResource": {
440                     "vimConnectionId": "string",
441                     "resourceProviderId": "string",
442                     "resourceId": "string",
443                     "vimLevelResourceType": "string"
444                 },
445                 "metadata": {},
446                 "affectedVnfcCpIds": [],
447                 "addedStorageResourceIds": [],
448                 "removedStorageResourceIds": [],
449             }],
450             "affectedVirtualLinks": [{
451                 "id": "string",
452                 "virtualLinkDescId": "string",
453                 "changeType": "ADDED",
454                 "networkResource": {
455                     "vimConnectionId": "string",
456                     "resourceProviderId": "string",
457                     "resourceId": "string",
458                     "vimLevelResourceType": "network",
459                 }
460             }],
461             "affectedVirtualStorages": [{
462                 "id": "string",
463                 "virtualStorageDescId": "string",
464                 "changeType": "ADDED",
465                 "storageResource": {
466                     "vimConnectionId": "string",
467                     "resourceProviderId": "string",
468                     "resourceId": "string",
469                     "vimLevelResourceType": "network",
470                 },
471                 "metadata": {}
472             }],
473             "changedInfo": {
474                 "vnfInstanceName": "string",
475                 "vnfInstanceDescription": "string",
476                 "vnfConfigurableProperties": {},
477                 "metadata": {},
478                 "extensions": {},
479                 "vimConnectionInfo": [{
480                     "id": "string",
481                     "vimId": "string",
482                     "vimType": "string",
483                     "interfaceInfo": {},
484                     "accessInfo": {},
485                     "extra": {}
486                 }],
487                 "vnfPkgId": "string",
488                 "vnfdId": "string",
489                 "vnfProvider": "string",
490                 "vnfProductName": "string",
491                 "vnfSoftwareVersion": "string",
492                 "vnfdVersion": "string"
493             },
494             "changedExtConnectivity": [{
495                 "id": "string",
496                 "resourceHandle": {
497                     "vimConnectionId": "string",
498                     "resourceProviderId": "string",
499                     "resourceId": "string",
500                     "vimLevelResourceType": "string"
501                 },
502                 "extLinkPorts": [{
503                     "id": "string",
504                     "resourceHandle": {
505                         "vimConnectionId": "string",
506                         "resourceProviderId": "string",
507                         "resourceId": "string",
508                         "vimLevelResourceType": "string"
509                     },
510                     "cpInstanceId": "string"
511                 }]
512             }]
513         }
514         response = self.client.post("/api/gvnfmdriver/v1/vnfs/lifecyclechangesnotification",
515                                     data=json.dumps(req_data),
516                                     content_type='application/json')
517         self.assertEqual(status.HTTP_200_OK, response.status_code)
518         expect_resp_data = None
519         self.assertEqual(expect_resp_data, response.data)
520
521     @mock.patch.object(restcall, 'call_req')
522     def test_get_vnfpkgs(self, mock_call_req):
523         vnfpkgs_info = {
524             "csars": [{
525                 "csarId": "1",
526                 "vnfdId": "2"
527             }]
528         }
529         mock_call_req.return_value = [0, json.JSONEncoder().encode(vnfpkgs_info), '200']
530         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
531         self.assertEqual(status.HTTP_200_OK, resp.status_code)
532         self.assertEqual(1, len(resp.data["csars"]))
533         self.assertEqual("1", resp.data["csars"][0]["csarId"])
534         self.assertEqual("2", resp.data["csars"][0]["vnfdId"])
535
536     @mock.patch.object(restcall, 'call_req')
537     def test_get_vnfpkgs_failed(self, mock_call_req):
538         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '200']
539         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
540         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)
541
542     @mock.patch.object(restcall, 'call_req')
543     def test_get_vnflcmopocc_with_id(self, mock_call_req):
544         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
545         vnfm_info = {
546             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
547             "name": "g_vnfm",
548             "type": "gvnfmdriver",
549             "vimId": "",
550             "vendor": "ZTE",
551             "version": "v1.0",
552             "description": "vnfm",
553             "certificateUrl": "",
554             "url": "http://10.74.44.11",
555             "userName": "admin",
556             "password": "admin",
557             "createTime": "2016-07-06 15:33:18"
558         }
559         dummy_single_vnf_lcm_op = {
560             "id": vnfLcmOpOccId,
561             "operationState": "STARTING",
562             "stateEnteredTime": "2018-07-09",
563             "startTime": "2018-07-09",
564             "vnfInstanceId": "cd552c9c-ab6f-11e8-b354-236c32aa91a1",
565             "grantId": None,
566             "operation": "SCALE",
567             "isAutomaticInvocation": False,
568             "operationParams": {},
569             "isCancelPending": False,
570             "cancelMode": None,
571             "error": None,
572             "resourceChanges": None,
573             "changedInfo": None,
574             "changedExtConnectivity": None,
575             "_links": {
576                 "self": {
577                     "href": "dem1o"
578                 },
579                 "vnfInstance": "demo"
580             }
581         }
582         mock_call_req.return_value = [0, json.JSONEncoder().encode(dummy_single_vnf_lcm_op), status.HTTP_200_OK]
583         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
584         self.assertEqual(dummy_single_vnf_lcm_op, resp.data)
585         self.assertEqual(status.HTTP_200_OK, resp.status_code)
586
587     @mock.patch.object(restcall, 'call_req')
588     def test_get_vnflcmopocc_failed(self, mock_call_req):
589         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
590         vnfm_info = {
591             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
592             "name": "g_vnfm",
593             "type": "gvnfmdriver",
594             "vimId": "",
595             "vendor": "ZTE",
596             "version": "v1.0",
597             "description": "vnfm",
598             "certificateUrl": "",
599             "url": "http://10.74.44.11",
600             "userName": "admin",
601             "password": "admin",
602             "createTime": "2016-07-06 15:33:18"
603         }
604         mock_call_req.return_value = [1, json.JSONEncoder().encode({}), status.HTTP_500_INTERNAL_SERVER_ERROR]
605         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
606         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)