c062c7c9d308fcdaddab8d869ea53cebd301ec0d
[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-3T11: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             # NOT REQUIERD #
294             # 'vimConnections': [],
295             # 'zones': [],
296             # 'zoneGroups': [],
297             # 'computeReservationId': None,
298             # 'networkReservationId': None,
299             # 'storageReservationId': None,
300             # 'addResources': None,
301             # 'tempResources': None,
302             # 'removeResource': None,
303             # 'updateResource': None,
304             # 'vimAssets': None,
305             # 'extVirtualLinks': None,
306             # 'extManagedVirtualLinks': None,
307             # 'additionalParams': None,
308             '_links': {
309                 'self': {'href': 'URI of this resource'},
310                 'vnfLcmOpOcc': {'href': 'Related VNF lifecycle management operation occurrence'},
311                 'vnfInstance': {'href': 'Related VNF instance'}
312             }
313         }
314
315         mock_call_req.return_value = [0, json.JSONEncoder().encode(grant), '201']
316         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
317                                    data=json.dumps(data), content_type='application/json')
318         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
319         expect_resp_data = {
320             'id': 'Identifier of the garnt',
321             'vnfInstanceId': 'Identifier of the related VNF instance',
322             'vnfLcmOpOccId': 'Identifier of the related VNF LcmOpOcc',
323             # NOT REQUIERD #
324             # 'vimConnections': [],
325             # 'zones': [],
326             # 'zoneGroups': [],
327             # 'computeReservationId': None,
328             # 'networkReservationId': None,
329             # 'storageReservationId': None,
330             # 'addResources': None,
331             # 'tempResources': None,
332             # 'removeResource': None,
333             # 'updateResource': None,
334             # 'vimAssets': None,
335             # 'extVirtualLinks': None,
336             # 'extManagedVirtualLinks': None,
337             # 'additionalParams': None,
338             '_links': {
339                 'self': {'href': 'URI of this resource'},
340                 'vnfLcmOpOcc': {'href': 'Related VNF lifecycle management operation occurrence'},
341                 'vnfInstance': {'href': 'Related VNF instance'}
342             }
343         }
344         self.assertDictEqual(expect_resp_data, response.data)
345
346     @mock.patch.object(restcall, 'call_req')
347     def test_grantvnf_failed(self, mock_call_req):
348         data = {
349             "vnfInstanceId": "1",
350             "vnfLcmOpOccId": "2",
351             "vnfdId": "3",
352             "flavourId": "4",
353             "operation": "INSTANTIATE",
354             "isAutomaticInvocation": True,
355             "instantiationLevelId": "5",
356             "addResources": [
357                 {
358                     "id": "1",
359                     "type": "COMPUTE",
360                     "vduId": "2",
361                     "resourceTemplateId": "3",
362                     "resourceTemplate": {
363                         "vimConnectionId": "4",
364                         "resourceProviderId": "5",
365                         "resourceId": "6",
366                         "vimLevelResourceType": "7"
367                     }
368                 }
369             ],
370             "placementConstraints": [
371                 {
372                     "affinityOrAntiAffinity": "AFFINITY",
373                     "scope": "NFVI_POP",
374                     "resource": [
375                         {
376                             "idType": "RES_MGMT",
377                             "resourceId": "1",
378                             "vimConnectionId": "2",
379                             "resourceProviderId": "3"
380                         }
381                     ]
382                 }
383             ],
384             "vimConstraints": [
385                 {
386                     "sameResourceGroup": True,
387                     "resource": [
388                         {
389                             "idType": "RES_MGMT",
390                             "resourceId": "1",
391                             "vimConnectionId": "2",
392                             "resourceProviderId": "3"
393                         }
394                     ]
395                 }
396             ],
397             "additionalParams": {},
398             "_links": {
399                 "vnfLcmOpOcc": {
400                     "href": "1"
401                 },
402                 "vnfInstance": {
403                     "href": "2"
404                 }
405             }
406         }
407         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '201']
408         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
409                                    data=json.dumps(data), content_type='application/json')
410         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code)
411
412     @mock.patch.object(restcall, 'call_req')
413     def test_notify(self, mock_call_req):
414         vim_info = {
415             "vim": {
416                 "vimInfoId": "111111",
417                 "vimId": "12345678",
418                 "interfaceInfo": {
419                     "vimType": "vnf",
420                     "apiVersion": "v1",
421                     "protocolType": "None"
422                 },
423                 "accessInfo": {
424                     "tenant": "tenant1",
425                     "username": "admin",
426                     "password": "password"
427                 },
428                 "interfaceEndpoint": "http://127.0.0.1/api/v1"
429             },
430             "zone": "",
431             "addResource": {
432                 "resourceDefinitionId": "xxxxx",
433                 "vimId": "12345678",
434                 "zoneId": "000"
435             },
436             "removeResource": "",
437             "vimAssets": {
438                 "computeResourceFlavour": {
439                     "vimId": "12345678",
440                     "vduId": "sdfasdf",
441                     "vimFlavourId": "12"
442                 },
443                 "softwareImage": {
444                     "vimId": "12345678",
445                     "imageName": "AAA",
446                     "vimImageId": ""
447                 }
448             },
449             "additionalParam": ""
450         }
451         r2 = [0, json.JSONEncoder().encode(vim_info), "200"]
452         mock_call_req.side_effect = [r2]
453         req_data = {
454             "vnfmInstId": "876543211",
455             "notificationType": "string",
456             "subscriptionId": "string",
457             "timeStamp": "1234567890",
458             "notificationStatus": "START",
459             "operationState": "STARTING",
460             "vnfInstanceId": "string",
461             "operation": "INSTANTIATE",
462             "isAutomaticInvocation": True,
463             "vnfLcmOpOccId": "string",
464             "affectedVnfcs": [{
465                 "id": "string",
466                 "vduId": "string",
467                 "changeType": "ADDED",
468                 "computeResource": {
469                     "vimConnectionId": "string",
470                     "resourceProviderId": "string",
471                     "resourceId": "string",
472                     "vimLevelResourceType": "string"
473                 },
474                 "metadata": {},
475                 "affectedVnfcCpIds": [],
476                 "addedStorageResourceIds": [],
477                 "removedStorageResourceIds": [],
478             }],
479             "affectedVirtualLinks": [{
480                 "id": "string",
481                 "virtualLinkDescId": "string",
482                 "changeType": "ADDED",
483                 "networkResource": {
484                     "vimConnectionId": "string",
485                     "resourceProviderId": "string",
486                     "resourceId": "string",
487                     "vimLevelResourceType": "network",
488                 }
489             }],
490             "affectedVirtualStorages": [{
491                 "id": "string",
492                 "virtualStorageDescId": "string",
493                 "changeType": "ADDED",
494                 "storageResource": {
495                     "vimConnectionId": "string",
496                     "resourceProviderId": "string",
497                     "resourceId": "string",
498                     "vimLevelResourceType": "network",
499                 },
500                 "metadata": {}
501             }],
502             "changedInfo": {
503                 "vnfInstanceName": "string",
504                 "vnfInstanceDescription": "string",
505                 "vnfConfigurableProperties": {},
506                 "metadata": {},
507                 "extensions": {},
508                 "vimConnectionInfo": [{
509                     "id": "string",
510                     "vimId": "string",
511                     "vimType": "string",
512                     "interfaceInfo": {},
513                     "accessInfo": {},
514                     "extra": {}
515                 }],
516                 "vnfPkgId": "string",
517                 "vnfdId": "string",
518                 "vnfProvider": "string",
519                 "vnfProductName": "string",
520                 "vnfSoftwareVersion": "string",
521                 "vnfdVersion": "string"
522             },
523             "changedExtConnectivity": [{
524                 "id": "string",
525                 "resourceHandle": {
526                     "vimConnectionId": "string",
527                     "resourceProviderId": "string",
528                     "resourceId": "string",
529                     "vimLevelResourceType": "string"
530                 },
531                 "extLinkPorts": [{
532                     "id": "string",
533                     "resourceHandle": {
534                         "vimConnectionId": "string",
535                         "resourceProviderId": "string",
536                         "resourceId": "string",
537                         "vimLevelResourceType": "string"
538                     },
539                     "cpInstanceId": "string"
540                 }]
541             }]
542         }
543         response = self.client.post("/api/gvnfmdriver/v1/vnfs/lifecyclechangesnotification",
544                                     data=json.dumps(req_data),
545                                     content_type='application/json')
546         self.assertEqual(status.HTTP_200_OK, response.status_code)
547         expect_resp_data = None
548         self.assertEqual(expect_resp_data, response.data)
549
550     @mock.patch.object(restcall, 'call_req')
551     def test_get_vnfpkgs(self, mock_call_req):
552         vnfpkgs_info = {
553             "csars": [{
554                 "csarId": "1",
555                 "vnfdId": "2"
556             }]
557         }
558         mock_call_req.return_value = [0, json.JSONEncoder().encode(vnfpkgs_info), '200']
559         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
560         self.assertEqual(status.HTTP_200_OK, resp.status_code)
561         self.assertEqual(1, len(resp.data["csars"]))
562         self.assertEqual("1", resp.data["csars"][0]["csarId"])
563         self.assertEqual("2", resp.data["csars"][0]["vnfdId"])
564
565     @mock.patch.object(restcall, 'call_req')
566     def test_get_vnfpkgs_failed(self, mock_call_req):
567         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '200']
568         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
569         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)
570
571     @mock.patch.object(restcall, 'call_req')
572     def test_get_vnflcmopocc_with_id(self, mock_call_req):
573         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
574         vnfm_info = {
575             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
576             "name": "g_vnfm",
577             "type": "gvnfmdriver",
578             "vimId": "",
579             "vendor": "ZTE",
580             "version": "v1.0",
581             "description": "vnfm",
582             "certificateUrl": "",
583             "url": "http://10.74.44.11",
584             "userName": "admin",
585             "password": "admin",
586             "createTime": "2016-07-06T15:33:18"
587         }
588         dummy_single_vnf_lcm_op = {
589             "id": vnfLcmOpOccId,
590             "operationState": "STARTING",
591             "stateEnteredTime": "2018-07-09",
592             "startTime": "2018-07-09",
593             "vnfInstanceId": "cd552c9c-ab6f-11e8-b354-236c32aa91a1",
594             "grantId": None,
595             "operation": "SCALE",
596             "isAutomaticInvocation": False,
597             "operationParams": {},
598             "isCancelPending": False,
599             "cancelMode": None,
600             "error": None,
601             "resourceChanges": None,
602             "changedInfo": None,
603             "changedExtConnectivity": None,
604             "_links": {
605                 "self": {
606                     "href": "dem1o"
607                 },
608                 "vnfInstance": "demo"
609             }
610         }
611         mock_call_req.return_value = [0, json.JSONEncoder().encode(dummy_single_vnf_lcm_op), status.HTTP_200_OK]
612         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
613         self.assertEqual(dummy_single_vnf_lcm_op, resp.data)
614         self.assertEqual(status.HTTP_200_OK, resp.status_code)
615
616     @mock.patch.object(restcall, 'call_req')
617     def test_get_vnflcmopocc_failed(self, mock_call_req):
618         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
619         vnfm_info = {
620             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
621             "name": "g_vnfm",
622             "type": "gvnfmdriver",
623             "vimId": "",
624             "vendor": "ZTE",
625             "version": "v1.0",
626             "description": "vnfm",
627             "certificateUrl": "",
628             "url": "http://10.74.44.11",
629             "userName": "admin",
630             "password": "admin",
631             "createTime": "2016-07-06 15:33:18"
632         }
633         mock_call_req.return_value = [1, json.JSONEncoder().encode({}), status.HTTP_500_INTERNAL_SERVER_ERROR]
634         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
635         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)
636
637     @mock.patch.object(restcall, 'call_req')
638     def test_subscribe_successfully(self, mock_call_req):
639         vnfm_info = {
640             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
641             "name": "g_vnfm",
642             "type": "gvnfmdriver",
643             "vimId": "",
644             "vendor": "ZTE",
645             "version": "v1.0",
646             "description": "vnfm",
647             "certificateUrl": "",
648             "url": "http://10.74.44.11",
649             "userName": "admin",
650             "password": "admin",
651             "createTime": "2016-07-06 15:33:18"
652         }
653         lccn_subscription_request_data = {
654             "filter": {
655                 "notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
656                 "operationTypes": ["INSTANTIATE"],
657                 "operationStates": ["STARTING"],
658             },
659             "callbackUri": "http://aurl.com",
660             "authentication": {
661                 "authType": ["BASIC"],
662                 "paramsBasic": {
663                     "username": "username",
664                     "password": "password"
665                 }
666             }
667         }
668         lccn_subscription_data = {
669             "id": "cd552c9c-ab6f-11e8-b354-236c32aa91a1",
670             "callbackUri": "http://aurl.com",
671             "filter": {
672                 "notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
673                 "operationTypes": ["INSTANTIATE"],
674                 "operationStates": ["STARTING"]
675             },
676             "_links": {
677                 "self": {"href": "URI of this resource."}
678             },
679         }
680         ret_of_vnfminfo_from_nslcm = [0, json.JSONEncoder().encode(vnfm_info), "200"]
681         ret_from_vnfm = [0, json.JSONEncoder().encode(lccn_subscription_data), status.HTTP_201_CREATED]
682         mock_call_req.side_effect = [ret_of_vnfminfo_from_nslcm, ret_from_vnfm]
683         response = self.client.post(
684             "/api/gvnfmdriver/v1/%s/subscriptions" % vnfm_info['vnfmId'],
685             json.dumps(lccn_subscription_request_data),
686             content_type='application/json'
687         )
688         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
689         self.assertEqual(lccn_subscription_data, response.data)
690
691     @mock.patch.object(restcall, 'call_req')
692     def test_subscribe_failed(self, mock_call_req):
693         vnfm_info = {
694             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
695             "name": "g_vnfm",
696             "type": "gvnfmdriver",
697             "vimId": "",
698             "vendor": "ZTE",
699             "version": "v1.0",
700             "description": "vnfm",
701             "certificateUrl": "",
702             "url": "http://10.74.44.11",
703             "userName": "admin",
704             "password": "admin",
705             "createTime": "2016-07-06 15:33:18"
706         }
707         lccn_subscription_request_data = {
708             "filter": {
709                 "notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
710                 "operationTypes": ["INSTANTIATE"],
711                 "operationStates": ["STARTING"],
712             },
713             "callbackUri": "http://aurl.com",
714             "authentication": {
715                 "authType": ["BASIC"],
716                 "paramsBasic": {
717                     "username": "username",
718                     "password": "password"
719                 }
720             }
721         }
722         ret_of_vnfminfo_from_nslcm = [0, json.JSONEncoder().encode(vnfm_info), "200"]
723         ret_from_vnfm = [1, None, status.HTTP_303_SEE_OTHER]
724         mock_call_req.side_effect = [ret_of_vnfminfo_from_nslcm, ret_from_vnfm]
725         response = self.client.post(
726             "/api/gvnfmdriver/v1/%s/subscriptions" % vnfm_info['vnfmId'],
727             json.dumps(lccn_subscription_request_data),
728             content_type='application/json'
729         )
730         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code)
731
732
733 # Operate API Test case
734     @mock.patch.object(restcall, 'call_req')
735     def test_operate_vnf_404_NotFound(self, mock_call_req):
736         vnfm_info = {
737             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
738             "name": "g_vnfm",
739             "type": "gvnfmdriver",
740             "vimId": "",
741             "vendor": "vendor1",
742             "version": "v1.0",
743             "description": "vnfm",
744             "certificateUrl": "",
745             "url": "http://10.74.44.11",
746             "userName": "admin",
747             "password": "admin",
748             "createTime": "2016-07-06 15:33:18"
749         }
750         req_data = {
751             "changeStateTo": "STARTED"
752         }
753         probDetail = {"status": 404, "detail": "VNF Instance not found"}
754         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
755         r2 = [1, json.JSONEncoder().encode(probDetail), "404", ""]
756         mock_call_req.side_effect = [r1, r2]
757         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/operate",
758                                     data=json.dumps(req_data), content_type="application/json")
759         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
760         self.assertEqual(probDetail, response.data)
761
762     @mock.patch.object(restcall, 'call_req')
763     def test_operate_vnf_409_Conflict(self, mock_call_req):
764         vnfm_info = {
765             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
766             "name": "g_vnfm",
767             "type": "gvnfmdriver",
768             "vimId": "",
769             "vendor": "vendor1",
770             "version": "v1.0",
771             "description": "vnfm",
772             "certificateUrl": "",
773             "url": "http://10.74.44.11",
774             "userName": "admin",
775             "password": "admin",
776             "createTime": "2016-07-06 15:33:18"
777         }
778         req_data = {
779             "changeStateTo": "STOPPED",
780             "stopType": "GRACEFUL",
781             "gracefulStopTimeout": 2
782         }
783         probDetail = {"status": 409, "detail": "VNF Instance not in Instantiated State"}
784         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
785         r2 = [1, json.JSONEncoder().encode(probDetail), "409", ""]
786         mock_call_req.side_effect = [r1, r2]
787         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/operate",
788                                     data=json.dumps(req_data), content_type="application/json")
789         self.assertEqual(status.HTTP_409_CONFLICT, response.status_code)
790         self.assertEqual(probDetail, response.data)
791
792     @mock.patch.object(restcall, 'call_req')
793     def test_operate_vnf_success(self, mock_call_req):
794         vnfm_info = {
795             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
796             "name": "g_vnfm",
797             "type": "gvnfmdriver",
798             "vimId": "",
799             "vendor": "vendor1",
800             "version": "v1.0",
801             "description": "vnfm",
802             "certificateUrl": "",
803             "url": "http://10.74.44.11",
804             "userName": "admin",
805             "password": "admin",
806             "createTime": "2016-07-06 15:33:18"
807         }
808         req_data = {
809             "changeStateTo": "STOPPED",
810             "stopType": "GRACEFUL",
811             "gracefulStopTimeout": 2
812         }
813         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
814         r2 = [0, json.JSONEncoder().encode(''), "202", "/vnf_lc_ops/NF-OPERATE-12-2a3be946-b01d-11e8-9302-08002705b121"]
815         mock_call_req.side_effect = [r1, r2]
816         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/operate",
817                                     data=json.dumps(req_data), content_type="application/json")
818         self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
819         self.assertEqual(None, response.data)
820         self.assertEqual("/vnf_lc_ops/NF-OPERATE-12-2a3be946-b01d-11e8-9302-08002705b121", response['Location'])
821
822 # Heal API
823     @mock.patch.object(restcall, 'call_req')
824     def test_heal_vnf_404_NotFound(self, mock_call_req):
825         vnfm_info = {
826             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
827             "name": "g_vnfm",
828             "type": "gvnfmdriver",
829             "vimId": "",
830             "vendor": "vendor1",
831             "version": "v1.0",
832             "description": "vnfm",
833             "certificateUrl": "",
834             "url": "http://10.74.44.11",
835             "userName": "admin",
836             "password": "admin",
837             "createTime": "2016-07-06 15:33:18"
838         }
839         req_data = {
840             "action": "vmReset",
841             "affectedvm": {
842                 "vmid": "1",
843                 "vduid": "vdu1Id",
844                 "vmname": "vduinstname"
845             }
846         }
847         probDetail = {"status": 404, "detail": "VNF Instance not found"}
848         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
849         r2 = [1, json.JSONEncoder().encode(probDetail), "404", ""]
850         mock_call_req.side_effect = [r1, r2]
851         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
852                                     data=json.dumps(req_data), content_type="application/json")
853         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
854         self.assertEqual(probDetail, response.data)
855
856     @mock.patch.object(restcall, 'call_req')
857     def test_heal_vnf_409_Conflict(self, mock_call_req):
858         vnfm_info = {
859             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
860             "name": "g_vnfm",
861             "type": "gvnfmdriver",
862             "vimId": "",
863             "vendor": "vendor1",
864             "version": "v1.0",
865             "description": "vnfm",
866             "certificateUrl": "",
867             "url": "http://10.74.44.11",
868             "userName": "admin",
869             "password": "admin",
870             "createTime": "2016-07-06 15:33:18"
871         }
872         req_data = {
873             "action": "vmReset",
874             "affectedvm": {
875                 "vmid": "1",
876                 "vduid": "vdu1Id",
877                 "vmname": "vduinstname"
878             }
879         }
880         probDetail = {"status": 409, "detail": "VNF Instance not in Instantiated State"}
881         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
882         r2 = [1, json.JSONEncoder().encode(probDetail), "409", ""]
883         mock_call_req.side_effect = [r1, r2]
884         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
885                                     data=json.dumps(req_data), content_type="application/json")
886         self.assertEqual(status.HTTP_409_CONFLICT, response.status_code)
887         self.assertEqual(probDetail, response.data)
888
889     @mock.patch.object(restcall, 'call_req')
890     def test_heal_vnf_success(self, mock_call_req):
891         vnfm_info = {
892             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
893             "name": "g_vnfm",
894             "type": "gvnfmdriver",
895             "vimId": "",
896             "vendor": "vendor1",
897             "version": "v1.0",
898             "description": "vnfm",
899             "certificateUrl": "",
900             "url": "http://10.74.44.11",
901             "userName": "admin",
902             "password": "admin",
903             "createTime": "2016-07-06 15:33:18"
904         }
905         req_data = {
906             "action": "vmReset",
907             "affectedvm": {
908                 "vmid": "1",
909                 "vduid": "vdu1Id",
910                 "vmname": "vduinstname"
911             }
912         }
913         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
914         r2 = [0, json.JSONEncoder().encode(''), "202", "/vnf_lc_ops/NF-HEAL-12-2a3be946-b01d-11e8-9302-08002705b121"]
915         mock_call_req.side_effect = [r1, r2]
916         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
917                                     data=json.dumps(req_data), content_type="application/json")
918         self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
919         self.assertEqual(None, response.data)
920         self.assertEqual("/vnf_lc_ops/NF-HEAL-12-2a3be946-b01d-11e8-9302-08002705b121", response['Location'])