Add instantiate test case
[vfc/nfvo/lcm.git] / lcm / ns / tests / test_sol_ns_instantiate_api.py
1 # Copyright 2019 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 import uuid
18
19 from mock import MagicMock
20 from django.test import TestCase
21 from rest_framework import status
22 from rest_framework.test import APIClient
23 from lcm.ns.biz.ns_instant import BuildInWorkflowThread
24 from lcm.ns.biz.ns_instant import InstantNSService
25 from lcm.pub.database.models import NSInstModel
26 from lcm.pub.utils import restcall
27 from lcm.pub.config import config
28
29 nsd_model = json.dumps({
30     "model": json.dumps({
31         "vnfs": [{
32             "vnf_id": "vnf1",
33             "properties": {
34                 "id": "vnfd1",
35                 "nf_type": "xgw"
36             },
37             "dependencies": [{
38                 "vl_id": "5"
39             }]
40         }],
41         "vls": [{
42             "vl_id": "5",
43             "properties": {}
44         }]
45     })
46 })
47
48 nsd = json.dumps({
49     "vnffgs": [
50     ],
51     "inputs": {
52     },
53     "pnfs": [
54         {
55             "pnf_id": "du",
56             "networks": [
57             ],
58             "description":"",
59             "properties":{
60                 "descriptor_id": "zte_ran_du_0001",
61                 "descriptor_invariant_id": "1111",
62                 "provider": "ZTE",
63                 "version": "1.0",
64                 "function_description": "RAN DU Function",
65                 "name": "ZTE RAN DU"
66             }
67         }
68     ],
69     "ns_exposed": {
70         "external_cps": [
71         ],
72         "forward_cps": [
73         ]
74     },
75     "graph": {
76         "cucp": [
77         ],
78         "du": [
79         ],
80         "vl_flat_net": [
81             "cucp",
82             "cuup"
83         ],
84         "vl_ext_net": [
85             "cucp",
86             "cuup"
87         ],
88         "cuup": [
89         ]
90     },
91     "basepath": "c:\\users\\10030173\\appdata\\local\\temp\\tmpvg5vto",
92     "vnfs": [
93         {
94             "networks": [
95                 {
96                     "key_name": "ran_ext_net",
97                     "vl_id": "vl_ext_net"
98                 },
99                 {
100                     "key_name": "ran_flat_net",
101                     "vl_id": "vl_flat_net"
102                 }
103             ],
104             "dependencies": [
105                 {
106                     "key_name": "ran_ext_net",
107                     "vl_id": "vl_ext_net"
108                 },
109                 {
110                     "key_name": "ran_flat_net",
111                     "vl_id": "vl_flat_net"
112                 }
113             ],
114             "vnf_id": "cucp",
115             "description": "",
116             "properties": {
117                 "descriptor_id": "zte_ran_cucp_0001",
118                 "flavour_description": "default",
119                 "software_version": "1.0.1",
120                 "flavour_id": "1",
121                 "descriptor_version": "1.0",
122                 "provider": "ZTE",
123                 "id": "zte_ran_cucp_0001",
124                 "vnfm_info": [
125                     "GVNFM-Driver"
126                 ],
127                 "product_name":"ran"
128             }
129         },
130         {
131             "networks": [
132                 {
133                     "key_name": "ran_ext_net",
134                     "vl_id": "vl_ext_net"
135                 },
136                 {
137                     "key_name": "ran_flat_net",
138                     "vl_id": "vl_flat_net"
139                 }
140             ],
141             "dependencies": [
142                 {
143                     "key_name": "ran_ext_net",
144                     "vl_id": "vl_ext_net"
145                 },
146                 {
147                     "key_name": "ran_flat_net",
148                     "vl_id": "vl_flat_net"
149                 }
150             ],
151             "vnf_id": "cuup",
152             "description": "",
153             "properties": {
154                 "descriptor_id": "zte_ran_cuup_0001",
155                 "flavour_description": "default",
156                 "software_version": "1.0.1",
157                 "flavour_id": "1",
158                 "descriptor_version": "1.0",
159                 "provider": "ZTE",
160                 "id": "zte_ran_cuup_0001",
161                 "vnfm_info": [
162                     "GVNFM-Driver"
163                 ],
164                 "product_name":"ran"
165             }
166         }
167     ],
168     "fps": [
169     ],
170     "vls": [
171         {
172             "vl_id": "vl_ext_net",
173             "description": "",
174             "properties": {
175                 "connectivity_type": {
176                     "layer_protocol": "ipv4"
177                 },
178                 "vl_profile": {
179                     "cidr": "10.0.0.0/24",
180                     "max_bit_rate_requirements": {
181                         "root": 10000000,
182                         "leaf": 10000000
183                     },
184                     "networkName": "ran_ext_net",
185                     "min_bit_rate_requirements": {
186                         "root": 10000000,
187                         "leaf": 10000000
188                     },
189                     "dhcpEnabled": False
190                 },
191                 "version": "1.0.1"
192             }
193         },
194         {
195             "vl_id": "vl_flat_net",
196             "description": "",
197             "properties": {
198                 "connectivity_type": {
199                     "layer_protocol": "ipv4"
200                 },
201                 "vl_profile": {
202                     "cidr": "10.1.0.0/24",
203                     "max_bit_rate_requirements": {
204                         "root": 10000000,
205                         "leaf": 10000000
206                     },
207                     "networkName": "ran_flat_net",
208                     "min_bit_rate_requirements": {
209                         "root": 10000000,
210                         "leaf": 10000000
211                     },
212                     "dhcpEnabled": False
213                 },
214                 "version": "1.0.1"
215             }
216         }
217     ],
218     "nested_ns": [
219     ],
220     "metadata": {
221         "template_name": "RAN-NS",
222         "template_version": "1.0",
223         "template_author": "ZTE"
224     }
225 })
226 vnfminfo = {"vnfmId": "1"}
227
228
229 class TestInstantiateNsApi(TestCase):
230
231     def setUp(self):
232         self.client = APIClient()
233         NSInstModel.objects.filter().delete()
234         self.url = "/api/nslcm/v1/ns_instances/%s/instantiate"
235         self.req_data = {
236             "additionalParamForNs": {
237                 "location": "CPE-DC_RegionOne"
238             },
239             "nsFlavourId": 'default',
240             "localizationLanguage": [{
241                 "vnfProfileId": "vnfd1",
242                 "locationConstraints": {
243                     "countryCode": "countryCode",
244                     # "vimId": "3",
245                     "civicAddressElement": [
246                         {"caType": "type1",
247                          "caValue": 1
248                          }
249                     ]
250                 }
251             }]
252         }
253         self.nsd_model = nsd_model
254         self.updated_nsd_model = {
255             "vnfs": [{
256                 "dependencies": [{
257                     "vl_id": "5"
258                 }],
259                 "vnf_id": "vnf1",
260                 "properties": {
261                     "nf_type": "xgw",
262                     "id": "vnfd1"
263                 }
264             }],
265             "vls": [{
266                 "vl_id": "5",
267                 "properties": {
268                     "location_info": {
269                         "vimid": "3"
270                     }
271                 }
272             }]
273         }
274         self.vnfms = json.dumps({
275             "esr-vnfm": [{
276                 "vnfm-id": "4"
277             }]
278         })
279         self.vnfm = json.dumps({
280             "type": "xgw",
281             "vim-id": "3",
282             "vnfm-id": "4",
283             "certificate-url": "http://127.0.0.0/ztevnfm/v1/auth",
284             "esr-system-info-list": {
285                 "esr-system-info": [{
286                     "type": "xgw",
287                     "vendor": "zte",
288                     "version": "1.0",
289                     "service-url": "http://127.0.0.0/ztevnfm/v1",
290                     "user-name": "admin",
291                     "password": "admin123"
292                 }]
293             }
294         })
295         # NSInstModel(id="2", nspackage_id="7", nsd_id="2", status="active").save()
296         self.nsInstanceId = str(uuid.uuid4())
297         NSInstModel(id=self.nsInstanceId, nspackage_id="7", nsd_id="2", status="active").save()
298
299     def tearDown(self):
300         pass
301
302     @mock.patch.object(restcall, 'call_req')
303     @mock.patch('lcm.pub.msapi.sdc_run_catalog.parse_nsd', MagicMock(return_value=nsd_model))
304     @mock.patch.object(BuildInWorkflowThread, 'run')
305     def test_ns_instantiate_when_succeed_to_enter_workflow(self, mock_run, mock_call_req):
306         config.WORKFLOW_OPTION = "buildin"
307         mock_call_req.side_effect = [
308             [0, self.nsd_model, '200'],
309             [0, self.vnfms, '200'],
310             [0, self.vnfm, '200']
311         ]
312         # response = self.client.post(self.url % '2', data=self.req_data, format='json')
313         response = self.client.post(self.url % self.nsInstanceId, data=self.req_data, format='json')
314         self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
315         self.assertIsNotNone(response['Location'])
316         response = self.client.get(response['Location'], format='json')
317         self.assertEqual(response.status_code, status.HTTP_200_OK)
318
319     @mock.patch.object(InstantNSService, 'do_biz')
320     def test_ns_instantiate_normal(self, mock_do_biz):
321         mock_do_biz.return_value = {'occ_id': "1"}
322         # resp = self.client.post(self.url % '2', data=self.req_data, format='json')
323         response = self.client.post(self.url % self.nsInstanceId, data=self.req_data, format='json')
324         # self.failUnlessEqual(status.HTTP_202_ACCEPTED, resp.status_code)
325         self.failUnlessEqual(status.HTTP_202_ACCEPTED, response.status_code)
326
327     @mock.patch.object(restcall, 'call_req')
328     def test_ns_instantiate_when_fail_to_parse_nsd(self, mock_call_req):
329         mock_call_req.return_value = [1, "Failed to parse nsd", '500']
330         # resp = self.client.post(self.url % '2', data=self.req_data, format='json')
331         resp = self.client.post(self.url % self.nsInstanceId, data=self.req_data, format='json')
332         self.assertEqual(resp.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
333
334     @mock.patch('lcm.ns.biz.ns_instantiate_flow.post_deal')
335     @mock.patch.object(restcall, 'call_req')
336     @mock.patch('lcm.ns.biz.ns_instantiate_flow.update_job')
337     @mock.patch('lcm.pub.msapi.sdc_run_catalog.parse_nsd', MagicMock(return_value=nsd))
338     @mock.patch('lcm.pub.msapi.extsys.select_vnfm', MagicMock(return_value=vnfminfo))
339     def test_ns_instantiate_with_pnf(self, mock_updata_job, mock_call_req, mock_post_deal):
340         config.WORKFLOW_OPTION = "grapflow"
341         # NSInstModel(id="1", name="test_ns", nspackage_id="1", status="created").save()
342         nsInstanceId = str(uuid.uuid4())
343         NSInstModel(id=nsInstanceId, name="test_ns", nspackage_id="1", status="created").save()
344         ret = [0, json.JSONEncoder().encode({'jobId': "1", "responseDescriptor": {"progress": 100}}), '200']
345         mock_call_req.side_effect = [ret for i in range(1, 20)]
346         data = {
347             "nsFlavourId": 'default',
348             "additionalParamForNs": {
349                 "sdnControllerId": "2"
350             },
351             "additionalParamsForVnf": [
352                 {
353                     "vnfProfileId": "zte_ran_cucp_0001",
354                     "additionalParams": {"vimId": '{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}'}
355                 },
356                 {
357                     "vnfProfileId": "zte_ran_cuup_0001",
358                     "additionalParams": {"vimId": '{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}'}
359                 }
360             ],
361             "addpnfData": [{
362                 "pnfId": 1,
363                 "pnfName": "test_pnf",
364                 "pnfdId": "zte_ran_du_0001",
365                 "pnfProfileId": "du"
366             }]
367         }
368         # response = self.client.post(self.url % '1', data=data, format='json')
369         response = self.client.post(self.url % nsInstanceId, data=data, format='json')
370         self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
371         self.assertIsNotNone(response['Location'])
372         response = self.client.get(response['Location'], format='json')
373         self.assertEqual(response.status_code, status.HTTP_200_OK)
374
375     def test_method_not_allowed(self):
376         # response = self.client.put(self.url % '1', data=self.req_data, format='json')
377         # self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
378         # response = self.client.patch(self.url % '1', data=self.req_data, format='json')
379         # self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
380         # response = self.client.delete(self.url % '1', data=self.req_data, format='json')
381         # self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
382         # response = self.client.get(self.url % '1', data=self.req_data, format='json')
383         # self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
384         response = self.client.put(self.url % self.nsInstanceId, data=self.req_data, format='json')
385         self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
386         response = self.client.patch(self.url % self.nsInstanceId, data=self.req_data, format='json')
387         self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
388         response = self.client.delete(self.url % self.nsInstanceId, data=self.req_data, format='json')
389         self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
390         response = self.client.get(self.url % self.nsInstanceId, data=self.req_data, format='json')
391         self.failUnlessEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response.status_code)
392
393     @mock.patch.object(restcall, 'call_req')
394     @mock.patch('lcm.pub.msapi.sdc_run_catalog.parse_nsd', MagicMock(return_value=nsd_model))
395     @mock.patch.object(BuildInWorkflowThread, 'run')
396     def test_ns_instantiate_vcpe(self, mock_run, mock_call_req):
397         config.WORKFLOW_OPTION = "buildin"
398         vcpe_nsd_model = json.dumps({
399             "model": json.dumps({
400                 "vnfs": [{
401                     "vnf_id": "b1bb0ce7-2222-4fa7-95ed-4840d70a1101",
402                     "properties": {
403                         "id": "vnfd0",
404                         "nf_type": "test"
405                     },
406                     "dependencies": [{
407                         "vl_id": "5"
408                     }]
409                 },
410                     {
411                         "vnf_id": "0408f076-e6c0-4c82-9940-272fddbb82de",
412                         "properties": {
413                             "id": "vnfd1",
414                             "nf_type": "test"
415                         },
416                         "dependencies": [{
417                             "vl_id": "5"
418                         }]
419                 },
420                     {
421                         "vnf_id": "b1bb0ce7-2222-4fa7-95ed-4840d70a1100",
422                         "properties": {
423                             "id": "vnfd2",
424                             "nf_type": "test"
425                         },
426                         "dependencies": [{
427                             "vl_id": "5"
428                         }]
429                 },
430                     {
431                         "vnf_id": "b1bb0ce7-2222-4fa7-95ed-4840d70a1102",
432                         "properties": {
433                             "id": "vnfd3",
434                             "nf_type": "test"
435                         },
436                         "dependencies": [{
437                             "vl_id": "5"
438                         }]
439                 },
440                     {
441                         "vnf_id": "3fca3543-07f5-492f-812c-ed462e4f94f4",
442                         "properties": {
443                             "id": "vnfd4",
444                             "nf_type": "test"
445                         },
446                         "dependencies": [{
447                             "vl_id": "5"
448                         }]
449                 },
450                 ],
451                 "vls": [{
452                     "vl_id": "5",
453                     "properties": {}
454                 }]
455             })
456         })
457         mock_call_req.side_effect = [
458             [0, vcpe_nsd_model, '200'],
459             [0, self.vnfms, '200'],
460             [0, self.vnfm, '200']
461         ]
462         req_data = {
463             "nsFlavourId": 'default',
464             "aditionalParamsForNs": {
465                 "nfvo": "vfc",
466                 "nf_naming": "true",
467                 "multi_stage_design": "false",
468                 "availability_zone_max_count": "1",
469                 "xyz": "123",
470                 "nsd0_providing_service_invariant_uuid": "12204a12-7da2-4ddf-8c2f-992a1a1acebf",
471                 "nsd0_providing_service_uuid": "5791dbeb-19d4-43e8-bf44-5b327ccf6bca"
472             },
473             "additionalParamsForVnf": [
474                 {
475                     "vnfProfileId": "b1bb0ce7-2222-4fa7-95ed-4840d70a1101",
476                     "additionalParams": {
477                         "vimId": "CloudOwner_regionOne"
478                     }
479                 },
480                 {
481                     "vnfProfileId": "0408f076-e6c0-4c82-9940-272fddbb82de",
482                     "additionalParams": {
483                         "vimId": "CloudOwner_regionOne"
484                     }
485                 },
486                 {
487                     "vnfProfileId": "b1bb0ce7-2222-4fa7-95ed-4840d70a1100",
488                     "additionalParams": {
489                         "vimId": "CloudOwner_regionOne"
490                     }
491                 },
492                 {
493                     "vnfProfileId": "b1bb0ce7-2222-4fa7-95ed-4840d70a1102",
494                     "additionalParams": {
495                         "vimId": "CloudOwner_regionOne"
496                     }
497                 },
498                 {
499                     "vnfProfileId": "3fca3543-07f5-492f-812c-ed462e4f94f4",
500                     "additionalParams": {
501                         "vimId": "CloudOwner_regionOne"
502                     }
503                 }
504             ]
505         }
506         # response = self.client.post(self.url % '2', data=req_data, format='json')
507         response = self.client.post(self.url % self.nsInstanceId, data=req_data, format='json')
508         self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code)
509         self.assertIsNotNone(response['Location'])
510         response = self.client.get(response['Location'], format='json')
511         self.assertEqual(response.status_code, status.HTTP_200_OK)