Update python2 to python3
[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_201_CREATED, response.status_code)
125
126     @mock.patch.object(restcall, 'call_req')
127     def test_query_vnf(self, mock_call_req):
128         vnfm_info = {
129             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
130             "name": "g_vnfm",
131             "type": "gvnfmdriver",
132             "vimId": "",
133             "vendor": "ZTE",
134             "version": "v1.0",
135             "description": "vnfm",
136             "certificateUrl": "",
137             "url": "http://10.74.44.11",
138             "userName": "admin",
139             "password": "admin",
140             "createTime": "2016-07-06 15:33:18"
141         }
142         job_info = {
143             "ResponseInfo": {
144                 "id": "88",
145                 "instantiationState": "INSTANTIATED",
146                 "vnfSoftwareVersion": "v1.2.3"
147             }
148         }
149         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
150         r2 = [0, json.JSONEncoder().encode(job_info), "200"]
151         mock_call_req.side_effect = [r1, r2]
152         response = self.client.get("/api/gvnfmdriver/v1/19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee/vnfs/88")
153         self.assertEqual(status.HTTP_200_OK, response.status_code)
154         expect_resp_data = {
155             "vnfInfo": {
156                 "vnfInstanceId": "88",
157                 "vnfStatus": "ACTIVE",
158                 "version": "v1.2.3"
159             }
160         }
161         self.assertEqual(expect_resp_data, response.data)
162
163     @mock.patch.object(restcall, 'call_req')
164     def test_operation_status(self, mock_call_req):
165         vnfm_info = {
166             'userName': 'admin',
167             'vendor': 'ZTE',
168             'name': 'ZTE_VNFM_237_62',
169             'vimId': '516cee95-e8ca-4d26-9268-38e343c2e31e',
170             'url': 'http: //192.168.237.165: 2324',
171             'certificateUrl': '',
172             'version': 'V1.0',
173             'vnfmId': 'b0797c9b-3da9-459c-b25c-3813e9d8fd70',
174             'password': 'admin',
175             'type': 'gvnfmdriver',
176             'createTime': '2016-10-3111: 08: 39',
177             'description': ''
178         }
179         expected_body = {
180             "jobId": "NF-CREATE-11-ec6c2f2a-9f48-11e6-9405-fa163e91c2f9",
181             "responseDescriptor": {
182                 "responseId": 3,
183                 "progress": 40,
184                 "status": "PROCESSING",
185                 "statusDescription": "OMC VMs are decommissioned in VIM",
186                 "errorCode": "null",
187                 "responseHistoryList": [
188                     {
189                         "status": "error",
190                         "progress": 255,
191                         "errorcode": "",
192                         "responseid": 20,
193                         "statusdescription": "'JsonParser' object has no attribute 'parser_info'"
194                     }
195                 ]
196             }
197         }
198         resp_body = {
199             "jobId": "NF-CREATE-11-ec6c2f2a-9f48-11e6-9405-fa163e91c2f9",
200             "responseDescriptor": {
201                 "responseId": 3,
202                 "progress": 40,
203                 "status": "PROCESSING",
204                 "statusDescription": "OMC VMs are decommissioned in VIM",
205                 "errorCode": "null",
206                 "responseHistoryList": [
207                     {
208                         "status": "error",
209                         "progress": 255,
210                         "errorcode": "",
211                         "responseid": 20,
212                         "statusdescription": "'JsonParser' object has no attribute 'parser_info'"
213                     }
214                 ]
215             }
216         }
217         r1 = [0, json.JSONEncoder().encode(vnfm_info), '200']
218         r2 = [0, json.JSONEncoder().encode(resp_body), '200']
219         mock_call_req.side_effect = [r1, r2]
220         response = self.client.get("/api/gvnfmdriver/v1/%s/jobs/%s?responseId=0"
221                                    % (vnfm_info["vnfmId"], expected_body["jobId"]))
222         self.assertEqual(status.HTTP_200_OK, response.status_code)
223         self.assertDictEqual(expected_body, response.data)
224
225     @mock.patch.object(restcall, 'call_req')
226     def test_grantvnf(self, mock_call_req):
227         data = {
228             "vnfInstanceId": "1",
229             "vnfLcmOpOccId": "2",
230             "vnfdId": "3",
231             "flavourId": "4",
232             "operation": "INSTANTIATE",
233             "isAutomaticInvocation": True,
234             "instantiationLevelId": "5",
235             "addResources": [
236                 {
237                     "id": "1",
238                     "type": "COMPUTE",
239                     "vduId": "2",
240                     "resourceTemplateId": "3",
241                     "resourceTemplate": {
242                         "vimConnectionId": "4",
243                         "resourceProviderId": "5",
244                         "resourceId": "6",
245                         "vimLevelResourceType": "7"
246                     }
247                 }
248             ],
249             "placementConstraints": [
250                 {
251                     "affinityOrAntiAffinity": "AFFINITY",
252                     "scope": "NFVI_POP",
253                     "resource": [
254                         {
255                             "idType": "RES_MGMT",
256                             "resourceId": "1",
257                             "vimConnectionId": "2",
258                             "resourceProviderId": "3"
259                         }
260                     ]
261                 }
262             ],
263             "vimConstraints": [
264                 {
265                     "sameResourceGroup": True,
266                     "resource": [
267                         {
268                             "idType": "RES_MGMT",
269                             "resourceId": "1",
270                             "vimConnectionId": "2",
271                             "resourceProviderId": "3"
272                         }
273                     ]
274                 }
275             ],
276             "additionalParams": {},
277             "_links": {
278                 "vnfLcmOpOcc": {
279                     "href": "1"
280                 },
281                 "vnfInstance": {
282                     "href": "2"
283                 }
284             }
285         }
286         grant = {
287             'id': 'Identifier of the garnt',
288             'vnfInstanceId': 'Identifier of the related VNF instance',
289             'vnfLcmOpOccId': 'Identifier of the related VNF LcmOpOcc',
290             # NOT REQUIERD #
291             # 'vimConnections': [],
292             # 'zones': [],
293             # 'zoneGroups': [],
294             # 'computeReservationId': None,
295             # 'networkReservationId': None,
296             # 'storageReservationId': None,
297             # 'addResources': None,
298             # 'tempResources': None,
299             # 'removeResource': None,
300             # 'updateResource': None,
301             # 'vimAssets': None,
302             # 'extVirtualLinks': None,
303             # 'extManagedVirtualLinks': None,
304             # 'additionalParams': None,
305             '_links': {
306                 'self': {'href': 'URI of this resource'},
307                 'vnfLcmOpOcc': {'href': 'Related VNF lifecycle management operation occurrence'},
308                 'vnfInstance': {'href': 'Related VNF instance'}
309             }
310         }
311
312         mock_call_req.return_value = [0, json.JSONEncoder().encode(grant), '201']
313         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
314                                    data=json.dumps(data), content_type='application/json')
315         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
316         expect_resp_data = {
317             'id': 'Identifier of the garnt',
318             'vnfInstanceId': 'Identifier of the related VNF instance',
319             'vnfLcmOpOccId': 'Identifier of the related VNF LcmOpOcc',
320             # NOT REQUIERD #
321             # 'vimConnections': [],
322             # 'zones': [],
323             # 'zoneGroups': [],
324             # 'computeReservationId': None,
325             # 'networkReservationId': None,
326             # 'storageReservationId': None,
327             # 'addResources': None,
328             # 'tempResources': None,
329             # 'removeResource': None,
330             # 'updateResource': None,
331             # 'vimAssets': None,
332             # 'extVirtualLinks': None,
333             # 'extManagedVirtualLinks': None,
334             # 'additionalParams': None,
335             '_links': {
336                 'self': {'href': 'URI of this resource'},
337                 'vnfLcmOpOcc': {'href': 'Related VNF lifecycle management operation occurrence'},
338                 'vnfInstance': {'href': 'Related VNF instance'}
339             }
340         }
341         self.assertDictEqual(expect_resp_data, response.data)
342
343     @mock.patch.object(restcall, 'call_req')
344     def test_grantvnf_failed(self, mock_call_req):
345         data = {
346             "vnfInstanceId": "1",
347             "vnfLcmOpOccId": "2",
348             "vnfdId": "3",
349             "flavourId": "4",
350             "operation": "INSTANTIATE",
351             "isAutomaticInvocation": True,
352             "instantiationLevelId": "5",
353             "addResources": [
354                 {
355                     "id": "1",
356                     "type": "COMPUTE",
357                     "vduId": "2",
358                     "resourceTemplateId": "3",
359                     "resourceTemplate": {
360                         "vimConnectionId": "4",
361                         "resourceProviderId": "5",
362                         "resourceId": "6",
363                         "vimLevelResourceType": "7"
364                     }
365                 }
366             ],
367             "placementConstraints": [
368                 {
369                     "affinityOrAntiAffinity": "AFFINITY",
370                     "scope": "NFVI_POP",
371                     "resource": [
372                         {
373                             "idType": "RES_MGMT",
374                             "resourceId": "1",
375                             "vimConnectionId": "2",
376                             "resourceProviderId": "3"
377                         }
378                     ]
379                 }
380             ],
381             "vimConstraints": [
382                 {
383                     "sameResourceGroup": True,
384                     "resource": [
385                         {
386                             "idType": "RES_MGMT",
387                             "resourceId": "1",
388                             "vimConnectionId": "2",
389                             "resourceProviderId": "3"
390                         }
391                     ]
392                 }
393             ],
394             "additionalParams": {},
395             "_links": {
396                 "vnfLcmOpOcc": {
397                     "href": "1"
398                 },
399                 "vnfInstance": {
400                     "href": "2"
401                 }
402             }
403         }
404         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '201']
405         response = self.client.put("/api/gvnfmdriver/v1/resource/grant",
406                                    data=json.dumps(data), content_type='application/json')
407         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code)
408
409     @mock.patch.object(restcall, 'call_req')
410     def test_notify(self, mock_call_req):
411         vim_info = {
412             "vim": {
413                 "vimInfoId": "111111",
414                 "vimId": "12345678",
415                 "interfaceInfo": {
416                     "vimType": "vnf",
417                     "apiVersion": "v1",
418                     "protocolType": "None"
419                 },
420                 "accessInfo": {
421                     "tenant": "tenant1",
422                     "username": "admin",
423                     "password": "password"
424                 },
425                 "interfaceEndpoint": "http://127.0.0.1/api/v1"
426             },
427             "zone": "",
428             "addResource": {
429                 "resourceDefinitionId": "xxxxx",
430                 "vimId": "12345678",
431                 "zoneId": "000"
432             },
433             "removeResource": "",
434             "vimAssets": {
435                 "computeResourceFlavour": {
436                     "vimId": "12345678",
437                     "vduId": "sdfasdf",
438                     "vimFlavourId": "12"
439                 },
440                 "softwareImage": {
441                     "vimId": "12345678",
442                     "imageName": "AAA",
443                     "vimImageId": ""
444                 }
445             },
446             "additionalParam": ""
447         }
448         r2 = [0, json.JSONEncoder().encode(vim_info), "200"]
449         mock_call_req.side_effect = [r2]
450         req_data = {
451             "vnfmInstId": "876543211",
452             "notificationType": "string",
453             "subscriptionId": "string",
454             "timeStamp": "1234567890",
455             "notificationStatus": "START",
456             "operationState": "STARTING",
457             "vnfInstanceId": "string",
458             "operation": "INSTANTIATE",
459             "isAutomaticInvocation": True,
460             "vnfLcmOpOccId": "string",
461             "affectedVnfcs": [{
462                 "id": "string",
463                 "vduId": "string",
464                 "changeType": "ADDED",
465                 "computeResource": {
466                     "vimConnectionId": "string",
467                     "resourceProviderId": "string",
468                     "resourceId": "string",
469                     "vimLevelResourceType": "string"
470                 },
471                 "metadata": {},
472                 "affectedVnfcCpIds": [],
473                 "addedStorageResourceIds": [],
474                 "removedStorageResourceIds": [],
475             }],
476             "affectedVirtualLinks": [{
477                 "id": "string",
478                 "virtualLinkDescId": "string",
479                 "changeType": "ADDED",
480                 "networkResource": {
481                     "vimConnectionId": "string",
482                     "resourceProviderId": "string",
483                     "resourceId": "string",
484                     "vimLevelResourceType": "network",
485                 }
486             }],
487             "affectedVirtualStorages": [{
488                 "id": "string",
489                 "virtualStorageDescId": "string",
490                 "changeType": "ADDED",
491                 "storageResource": {
492                     "vimConnectionId": "string",
493                     "resourceProviderId": "string",
494                     "resourceId": "string",
495                     "vimLevelResourceType": "network",
496                 },
497                 "metadata": {}
498             }],
499             "changedInfo": {
500                 "vnfInstanceName": "string",
501                 "vnfInstanceDescription": "string",
502                 "vnfConfigurableProperties": {},
503                 "metadata": {},
504                 "extensions": {},
505                 "vimConnectionInfo": [{
506                     "id": "string",
507                     "vimId": "string",
508                     "vimType": "string",
509                     "interfaceInfo": {},
510                     "accessInfo": {},
511                     "extra": {}
512                 }],
513                 "vnfPkgId": "string",
514                 "vnfdId": "string",
515                 "vnfProvider": "string",
516                 "vnfProductName": "string",
517                 "vnfSoftwareVersion": "string",
518                 "vnfdVersion": "string"
519             },
520             "changedExtConnectivity": [{
521                 "id": "string",
522                 "resourceHandle": {
523                     "vimConnectionId": "string",
524                     "resourceProviderId": "string",
525                     "resourceId": "string",
526                     "vimLevelResourceType": "string"
527                 },
528                 "extLinkPorts": [{
529                     "id": "string",
530                     "resourceHandle": {
531                         "vimConnectionId": "string",
532                         "resourceProviderId": "string",
533                         "resourceId": "string",
534                         "vimLevelResourceType": "string"
535                     },
536                     "cpInstanceId": "string"
537                 }]
538             }]
539         }
540         response = self.client.post("/api/gvnfmdriver/v1/vnfs/lifecyclechangesnotification",
541                                     data=json.dumps(req_data),
542                                     content_type='application/json')
543         self.assertEqual(status.HTTP_200_OK, response.status_code)
544         expect_resp_data = None
545         self.assertEqual(expect_resp_data, response.data)
546
547     @mock.patch.object(restcall, 'call_req')
548     def test_get_vnfpkgs(self, mock_call_req):
549         vnfpkgs_info = {
550             "csars": [{
551                 "csarId": "1",
552                 "vnfdId": "2"
553             }]
554         }
555         mock_call_req.return_value = [0, json.JSONEncoder().encode(vnfpkgs_info), '200']
556         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
557         self.assertEqual(status.HTTP_200_OK, resp.status_code)
558         self.assertEqual(1, len(resp.data["csars"]))
559         self.assertEqual("1", resp.data["csars"][0]["csarId"])
560         self.assertEqual("2", resp.data["csars"][0]["vnfdId"])
561
562     @mock.patch.object(restcall, 'call_req')
563     def test_get_vnfpkgs_failed(self, mock_call_req):
564         mock_call_req.return_value = [1, json.JSONEncoder().encode(""), '200']
565         resp = self.client.get("/api/gvnfmdriver/v1/vnfpackages")
566         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)
567
568     @mock.patch.object(restcall, 'call_req')
569     def test_get_vnflcmopocc_with_id(self, mock_call_req):
570         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
571         vnfm_info = {
572             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
573             "name": "g_vnfm",
574             "type": "gvnfmdriver",
575             "vimId": "",
576             "vendor": "ZTE",
577             "version": "v1.0",
578             "description": "vnfm",
579             "certificateUrl": "",
580             "url": "http://10.74.44.11",
581             "userName": "admin",
582             "password": "admin",
583             "createTime": "2016-07-06T15:33:18"
584         }
585         dummy_single_vnf_lcm_op = {
586             "id": vnfLcmOpOccId,
587             "operationState": "STARTING",
588             "stateEnteredTime": "2018-07-09",
589             "startTime": "2018-07-09",
590             "vnfInstanceId": "cd552c9c-ab6f-11e8-b354-236c32aa91a1",
591             "grantId": None,
592             "operation": "SCALE",
593             "isAutomaticInvocation": False,
594             "operationParams": {},
595             "isCancelPending": False,
596             "cancelMode": None,
597             "error": None,
598             "resourceChanges": None,
599             "changedInfo": None,
600             "changedExtConnectivity": None,
601             "_links": {
602                 "self": {
603                     "href": "dem1o"
604                 },
605                 "vnfInstance": "demo"
606             }
607         }
608         mock_call_req.return_value = [0, json.JSONEncoder().encode(dummy_single_vnf_lcm_op), status.HTTP_200_OK]
609         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
610         self.assertEqual(dummy_single_vnf_lcm_op, resp.data)
611         self.assertEqual(status.HTTP_200_OK, resp.status_code)
612
613     @mock.patch.object(restcall, 'call_req')
614     def test_get_vnflcmopocc_failed(self, mock_call_req):
615         vnfLcmOpOccId = "99442b18-a5c7-11e8-998c-bf1755941f16"
616         vnfm_info = {
617             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
618             "name": "g_vnfm",
619             "type": "gvnfmdriver",
620             "vimId": "",
621             "vendor": "ZTE",
622             "version": "v1.0",
623             "description": "vnfm",
624             "certificateUrl": "",
625             "url": "http://10.74.44.11",
626             "userName": "admin",
627             "password": "admin",
628             "createTime": "2016-07-06 15:33:18"
629         }
630         mock_call_req.return_value = [1, json.JSONEncoder().encode({}), status.HTTP_500_INTERNAL_SERVER_ERROR]
631         resp = self.client.get("/api/gvnfmdriver/v1/%s/vnf_lcm_op_occs/%s" % (vnfm_info['vnfmId'], vnfLcmOpOccId))
632         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, resp.status_code)
633
634     @mock.patch.object(restcall, 'call_req')
635     def test_subscribe_successfully(self, mock_call_req):
636         vnfm_info = {
637             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
638             "name": "g_vnfm",
639             "type": "gvnfmdriver",
640             "vimId": "",
641             "vendor": "ZTE",
642             "version": "v1.0",
643             "description": "vnfm",
644             "certificateUrl": "",
645             "url": "http://10.74.44.11",
646             "userName": "admin",
647             "password": "admin",
648             "createTime": "2016-07-06 15:33:18"
649         }
650         lccn_subscription_request_data = {
651             "filter": {
652                 "notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
653                 "operationTypes": ["INSTANTIATE"],
654                 "operationStates": ["STARTING"]
655             },
656             "callbackUri": "http://aurl.com",
657             "authentication": {
658                 "authType": ["BASIC"],
659                 "paramsBasic": {
660                     "username": "username",
661                     "password": "password"
662                 }
663             }
664         }
665         lccn_subscription_data = {
666             "id": "cd552c9c-ab6f-11e8-b354-236c32aa91a1",
667             "callbackUri": "http://aurl.com",
668             "filter": {
669                 "notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
670                 "operationTypes": ["INSTANTIATE"],
671                 "operationStates": ["STARTING"]
672             },
673             "_links": {
674                 "self": {"href": "URI of this resource."}
675             },
676         }
677         ret_of_vnfminfo_from_nslcm = [0, json.JSONEncoder().encode(vnfm_info), "200"]
678         ret_from_vnfm = [0, json.JSONEncoder().encode(lccn_subscription_data), status.HTTP_201_CREATED]
679         mock_call_req.side_effect = [ret_of_vnfminfo_from_nslcm, ret_from_vnfm]
680         response = self.client.post(
681             "/api/gvnfmdriver/v1/%s/subscriptions" % vnfm_info['vnfmId'],
682             json.dumps(lccn_subscription_request_data),
683             content_type='application/json'
684         )
685         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
686         self.assertEqual(lccn_subscription_data, response.data)
687
688     @mock.patch.object(restcall, 'call_req')
689     def test_subscribe_failed(self, mock_call_req):
690         vnfm_info = {
691             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
692             "name": "g_vnfm",
693             "type": "gvnfmdriver",
694             "vimId": "",
695             "vendor": "ZTE",
696             "version": "v1.0",
697             "description": "vnfm",
698             "certificateUrl": "",
699             "url": "http://10.74.44.11",
700             "userName": "admin",
701             "password": "admin",
702             "createTime": "2016-07-06 15:33:18"
703         }
704         lccn_subscription_request_data = {
705             "filter": {
706                 "notificationTypes": ["VnfLcmOperationOccurrenceNotification"],
707                 "operationTypes": ["INSTANTIATE"],
708                 "operationStates": ["STARTING"],
709             },
710             "callbackUri": "http://aurl.com",
711             "authentication": {
712                 "authType": ["BASIC"],
713                 "paramsBasic": {
714                     "username": "username",
715                     "password": "password"
716                 }
717             }
718         }
719         ret_of_vnfminfo_from_nslcm = [0, json.JSONEncoder().encode(vnfm_info), "200"]
720         ret_from_vnfm = [1, None, status.HTTP_303_SEE_OTHER]
721         mock_call_req.side_effect = [ret_of_vnfminfo_from_nslcm, ret_from_vnfm]
722         response = self.client.post(
723             "/api/gvnfmdriver/v1/%s/subscriptions" % vnfm_info['vnfmId'],
724             json.dumps(lccn_subscription_request_data),
725             content_type='application/json'
726         )
727         self.assertEqual(status.HTTP_500_INTERNAL_SERVER_ERROR, response.status_code)
728
729     @mock.patch.object(restcall, 'call_req')
730     def test_operate_vnf_404_NotFound(self, mock_call_req):
731         vnfm_info = {
732             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
733             "name": "g_vnfm",
734             "type": "gvnfmdriver",
735             "vimId": "",
736             "vendor": "vendor1",
737             "version": "v1.0",
738             "description": "vnfm",
739             "certificateUrl": "",
740             "url": "http://10.74.44.11",
741             "userName": "admin",
742             "password": "admin",
743             "createTime": "2016-07-06 15:33:18"
744         }
745         req_data = {
746             "changeStateTo": "STARTED"
747         }
748         probDetail = {"status": 404, "detail": "VNF Instance not found"}
749         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
750         r2 = [1, json.JSONEncoder().encode(probDetail), "404", ""]
751         mock_call_req.side_effect = [r1, r2]
752         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/operate",
753                                     data=json.dumps(req_data), content_type="application/json")
754         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
755         self.assertEqual(probDetail, response.data)
756
757     @mock.patch.object(restcall, 'call_req')
758     def test_operate_vnf_409_Conflict(self, mock_call_req):
759         vnfm_info = {
760             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
761             "name": "g_vnfm",
762             "type": "gvnfmdriver",
763             "vimId": "",
764             "vendor": "vendor1",
765             "version": "v1.0",
766             "description": "vnfm",
767             "certificateUrl": "",
768             "url": "http://10.74.44.11",
769             "userName": "admin",
770             "password": "admin",
771             "createTime": "2016-07-06 15:33:18"
772         }
773         req_data = {
774             "changeStateTo": "STOPPED",
775             "stopType": "GRACEFUL",
776             "gracefulStopTimeout": 2
777         }
778         probDetail = {"status": 409, "detail": "VNF Instance not in Instantiated State"}
779         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
780         r2 = [1, json.JSONEncoder().encode(probDetail), "409", ""]
781         mock_call_req.side_effect = [r1, r2]
782         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/operate",
783                                     data=json.dumps(req_data), content_type="application/json")
784         self.assertEqual(status.HTTP_409_CONFLICT, response.status_code)
785         self.assertEqual(probDetail, response.data)
786
787     @mock.patch.object(restcall, 'call_req')
788     def test_operate_vnf_success(self, mock_call_req):
789         vnfm_info = {
790             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
791             "name": "g_vnfm",
792             "type": "gvnfmdriver",
793             "vimId": "",
794             "vendor": "vendor1",
795             "version": "v1.0",
796             "description": "vnfm",
797             "certificateUrl": "",
798             "url": "http://10.74.44.11",
799             "userName": "admin",
800             "password": "admin",
801             "createTime": "2016-07-06 15:33:18"
802         }
803         req_data = {
804             "changeStateTo": "STOPPED",
805             "stopType": "GRACEFUL",
806             "gracefulStopTimeout": 2
807         }
808         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
809         r2 = [0, json.JSONEncoder().encode(''), "202", "/vnf_lc_ops/NF-OPERATE-12-2a3be946-b01d-11e8-9302-08002705b121"]
810         mock_call_req.side_effect = [r1, r2]
811         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/operate",
812                                     data=json.dumps(req_data), content_type="application/json")
813         self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
814         self.assertEqual("/vnf_lc_ops/NF-OPERATE-12-2a3be946-b01d-11e8-9302-08002705b121", response['Location'])
815
816 # Heal API
817     @mock.patch.object(restcall, 'call_req')
818     def test_heal_vnf_404_NotFound(self, mock_call_req):
819         vnfm_info = {
820             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
821             "name": "g_vnfm",
822             "type": "gvnfmdriver",
823             "vimId": "",
824             "vendor": "vendor1",
825             "version": "v1.0",
826             "description": "vnfm",
827             "certificateUrl": "",
828             "url": "http://10.74.44.11",
829             "userName": "admin",
830             "password": "admin",
831             "createTime": "2016-07-06 15:33:18"
832         }
833         req_data = {
834             "action": "vmReset",
835             "affectedvm": {
836                 "vmid": "1",
837                 "vduid": "vdu1Id",
838                 "vmname": "vduinstname"
839             }
840         }
841         probDetail = {"status": 404, "detail": "VNF Instance not found"}
842         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
843         r2 = [1, json.JSONEncoder().encode(probDetail), "404", ""]
844         mock_call_req.side_effect = [r1, r2]
845         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
846                                     data=json.dumps(req_data), content_type="application/json")
847         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
848         self.assertEqual(probDetail, response.data)
849
850     @mock.patch.object(restcall, 'call_req')
851     def test_heal_vnf_409_Conflict(self, mock_call_req):
852         vnfm_info = {
853             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
854             "name": "g_vnfm",
855             "type": "gvnfmdriver",
856             "vimId": "",
857             "vendor": "vendor1",
858             "version": "v1.0",
859             "description": "vnfm",
860             "certificateUrl": "",
861             "url": "http://10.74.44.11",
862             "userName": "admin",
863             "password": "admin",
864             "createTime": "2016-07-06 15:33:18"
865         }
866         req_data = {
867             "action": "vmReset",
868             "affectedvm": {
869                 "vmid": "1",
870                 "vduid": "vdu1Id",
871                 "vmname": "vduinstname"
872             }
873         }
874         probDetail = {"status": 409, "detail": "VNF Instance not in Instantiated State"}
875         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200", ""]
876         r2 = [1, json.JSONEncoder().encode(probDetail), "409", ""]
877         mock_call_req.side_effect = [r1, r2]
878         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
879                                     data=json.dumps(req_data), content_type="application/json")
880         self.assertEqual(status.HTTP_409_CONFLICT, response.status_code)
881         self.assertEqual(probDetail, response.data)
882
883     @mock.patch.object(restcall, 'call_req')
884     def test_heal_vnf_success(self, mock_call_req):
885         vnfm_info = {
886             "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
887             "name": "g_vnfm",
888             "type": "gvnfmdriver",
889             "vimId": "",
890             "vendor": "vendor1",
891             "version": "v1.0",
892             "description": "vnfm",
893             "certificateUrl": "",
894             "url": "http://10.74.44.11",
895             "userName": "admin",
896             "password": "admin",
897             "createTime": "2016-07-06 15:33:18"
898         }
899         req_data = {
900             "action": "vmReset",
901             "affectedvm": {
902                 "vmid": "1",
903                 "vduid": "vdu1Id",
904                 "vmname": "vduinstname"
905             }
906         }
907         r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
908         r2 = [0, json.JSONEncoder().encode(''), "202", "/vnf_lc_ops/NF-HEAL-12-2a3be946-b01d-11e8-9302-08002705b121"]
909         mock_call_req.side_effect = [r1, r2]
910         response = self.client.post("/api/gvnfmdriver/v1/vnfmid/vnfs/2/heal",
911                                     data=json.dumps(req_data), content_type="application/json")
912         self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
913         self.assertEqual(None, response.data)
914         self.assertEqual("/vnf_lc_ops/NF-HEAL-12-2a3be946-b01d-11e8-9302-08002705b121", response['Location'])
915
916     def test_health_check(self):
917         response = self.client.get("/api/gvnfmdriver/v1/health_check")
918         self.assertEqual(status.HTTP_200_OK, response.status_code, response.content)
919         resp_data = json.loads(response.content)
920         self.assertEqual({"status": "active"}, resp_data)