1 # Copyright 2019 ZTE Corporation.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
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
29 nsd_model = json.dumps({
60 "descriptor_id": "zte_ran_du_0001",
61 "descriptor_invariant_id": "1111",
64 "function_description": "RAN DU Function",
91 "basepath": "c:\\users\\10030173\\appdata\\local\\temp\\tmpvg5vto",
96 "key_name": "ran_ext_net",
100 "key_name": "ran_flat_net",
101 "vl_id": "vl_flat_net"
106 "key_name": "ran_ext_net",
107 "vl_id": "vl_ext_net"
110 "key_name": "ran_flat_net",
111 "vl_id": "vl_flat_net"
117 "descriptor_id": "zte_ran_cucp_0001",
118 "flavour_description": "default",
119 "software_version": "1.0.1",
121 "descriptor_version": "1.0",
123 "id": "zte_ran_cucp_0001",
133 "key_name": "ran_ext_net",
134 "vl_id": "vl_ext_net"
137 "key_name": "ran_flat_net",
138 "vl_id": "vl_flat_net"
143 "key_name": "ran_ext_net",
144 "vl_id": "vl_ext_net"
147 "key_name": "ran_flat_net",
148 "vl_id": "vl_flat_net"
154 "descriptor_id": "zte_ran_cuup_0001",
155 "flavour_description": "default",
156 "software_version": "1.0.1",
158 "descriptor_version": "1.0",
160 "id": "zte_ran_cuup_0001",
172 "vl_id": "vl_ext_net",
175 "connectivity_type": {
176 "layer_protocol": "ipv4"
179 "cidr": "10.0.0.0/24",
180 "max_bit_rate_requirements": {
184 "networkName": "ran_ext_net",
185 "min_bit_rate_requirements": {
195 "vl_id": "vl_flat_net",
198 "connectivity_type": {
199 "layer_protocol": "ipv4"
202 "cidr": "10.1.0.0/24",
203 "max_bit_rate_requirements": {
207 "networkName": "ran_flat_net",
208 "min_bit_rate_requirements": {
221 "template_name": "RAN-NS",
222 "template_version": "1.0",
223 "template_author": "ZTE"
226 vnfminfo = {"vnfmId": "1"}
229 class TestInstantiateNsApi(TestCase):
232 self.client = APIClient()
233 NSInstModel.objects.filter().delete()
234 self.url = "/api/nslcm/v1/ns_instances/%s/instantiate"
236 "additionalParamForNs": {
237 "location": "CPE-DC_RegionOne"
239 "nsFlavourId": 'default',
240 "localizationLanguage": [{
241 "vnfProfileId": "vnfd1",
242 "locationConstraints": {
243 "countryCode": "countryCode",
245 "civicAddressElement": [
253 self.nsd_model = nsd_model
254 self.updated_nsd_model = {
274 self.vnfms = json.dumps({
279 self.vnfm = json.dumps({
283 "certificate-url": "http://127.0.0.0/ztevnfm/v1/auth",
284 "esr-system-info-list": {
285 "esr-system-info": [{
289 "service-url": "http://127.0.0.0/ztevnfm/v1",
290 "user-name": "admin",
291 "password": "admin123"
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()
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']
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)
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)
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)
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)]
347 "nsFlavourId": 'default',
348 "additionalParamForNs": {
349 "sdnControllerId": "2"
351 "additionalParamsForVnf": [
353 "vnfProfileId": "zte_ran_cucp_0001",
354 "additionalParams": {"vimId": '{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}'}
357 "vnfProfileId": "zte_ran_cuup_0001",
358 "additionalParams": {"vimId": '{"cloud_owner": "VCPE", "cloud_regionid": "RegionOne"}'}
363 "pnfName": "test_pnf",
364 "pnfdId": "zte_ran_du_0001",
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)
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)
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({
401 "vnf_id": "b1bb0ce7-2222-4fa7-95ed-4840d70a1101",
411 "vnf_id": "0408f076-e6c0-4c82-9940-272fddbb82de",
421 "vnf_id": "b1bb0ce7-2222-4fa7-95ed-4840d70a1100",
431 "vnf_id": "b1bb0ce7-2222-4fa7-95ed-4840d70a1102",
441 "vnf_id": "3fca3543-07f5-492f-812c-ed462e4f94f4",
457 mock_call_req.side_effect = [
458 [0, vcpe_nsd_model, '200'],
459 [0, self.vnfms, '200'],
460 [0, self.vnfm, '200']
463 "nsFlavourId": 'default',
464 "aditionalParamsForNs": {
467 "multi_stage_design": "false",
468 "availability_zone_max_count": "1",
470 "nsd0_providing_service_invariant_uuid": "12204a12-7da2-4ddf-8c2f-992a1a1acebf",
471 "nsd0_providing_service_uuid": "5791dbeb-19d4-43e8-bf44-5b327ccf6bca"
473 "additionalParamsForVnf": [
475 "vnfProfileId": "b1bb0ce7-2222-4fa7-95ed-4840d70a1101",
476 "additionalParams": {
477 "vimId": "CloudOwner_regionOne"
481 "vnfProfileId": "0408f076-e6c0-4c82-9940-272fddbb82de",
482 "additionalParams": {
483 "vimId": "CloudOwner_regionOne"
487 "vnfProfileId": "b1bb0ce7-2222-4fa7-95ed-4840d70a1100",
488 "additionalParams": {
489 "vimId": "CloudOwner_regionOne"
493 "vnfProfileId": "b1bb0ce7-2222-4fa7-95ed-4840d70a1102",
494 "additionalParams": {
495 "vimId": "CloudOwner_regionOne"
499 "vnfProfileId": "3fca3543-07f5-492f-812c-ed462e4f94f4",
500 "additionalParams": {
501 "vimId": "CloudOwner_regionOne"
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)