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