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