1 # Copyright 2017 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.
16 from rest_framework import status
17 from django.test import TestCase
18 from django.test import Client
20 from lcm.pub.utils import restcall, toscaparser
21 from lcm.pub.database.models import NSDModel, NSInstModel, NfPackageModel
22 from lcm.pub.msapi import sdc
25 class TestSdcNsPackage(TestCase):
27 self.client = Client()
28 NSDModel.objects.filter().delete()
29 NSInstModel.objects.filter().delete()
30 NfPackageModel.objects.filter().delete()
52 "number_of_endpoints": 3,
53 "dependent_virtual_link": [
64 "value": "sfc_data_network"
66 "externalDataNetworkName": {
68 "value": "vlan_4004_tunnel_net"
70 "externalManageNetworkName": {
72 "value": "vlan_4008_mng_net"
76 "value": "192.167.0.10-192.168.0.20"
78 "externalPluginManageNetworkName": {
80 "value": "vlan_4007_plugin_net"
90 "request_reclassification": False ,
93 "management_address": "111111",
106 "dest_port_range": "1-100",
107 "ip_protocol": "tcp",
109 "119.1.1.1-119.1.1.10"
113 "get_input": "NatIpRange"
117 "source_port_range": "1-100"
125 "node_name": "m6000_data_out"
130 "node_name": "m600_tunnel_cp"
133 "capability": "vnat_fw_inout",
147 "dest_port_range": "1-100",
148 "ip_protocol": "tcp",
156 "source_port_range": "1-100"
164 "node_name": "m6000_data_in"
169 "node_name": "m600_tunnel_cp"
172 "capability": "vfw_fw_inout",
177 "capability": "vnat_fw_inout",
184 "node_name": "m600_tunnel_cp"
189 "node_name": "m6000_data_out"
202 "plugin_info": "vbrasplugin_1.0",
205 "adjust_vnf_capacity": True,
207 "vnf_extend_type": "driver",
208 "csarVersion": "v1.0",
210 "csarProvider": "ZTE",
215 "vmnumber_overquota_alarm": True,
216 "vnfd_version": "1.0.0",
217 "externalPluginManageNetworkName": "vlan_4007_plugin_net",
218 "id": "vcpe_vfw_zte_1_0",
219 "request_reclassification": False
223 "key_name": "vfw_ctrl_by_manager_cp",
224 "vl_id": "ext_mnet_net"
227 "key_name": "vfw_data_cp",
228 "vl_id": "sfc_data_network"
231 "type": "tosca.nodes.nfv.ext.zte.VNF.VFW",
241 "file_url": "policies/abc.drl",
248 "vl_id": "ext_mnet_net",
249 "route_external": False ,
252 "name": "vlan_4008_mng_net",
257 "availability_zone": "nova"
260 "dhcp_enabled": True,
261 "network_name": "vlan_4008_mng_net",
262 "network_type": "vlan"
267 "vl_id": "ext_datanet_net",
268 "route_external": False ,
271 "name": "vlan_4004_tunnel_net",
276 "availability_zone": "nova"
279 "dhcp_enabled": True,
280 "network_name": "vlan_4004_tunnel_net",
281 "network_type": "vlan"
286 "vl_id": "sfc_data_network",
287 "route_external": False ,
290 "name": "sfc_data_network",
291 "dhcp_enabled": True,
292 "is_predefined": False ,
296 "availability_zone": "nova"
300 "network_name": "sfc_data_network",
301 "network_type": "vlan"
310 "cp_id": "m6000_data_out",
312 "direction": "bidirectional",
313 "vnic_type": "normal",
315 "mac_address": "11-22-33-22-11-44",
316 "interface_name": "xgei-0/4/1/5",
317 "ip_address": "176.1.1.2",
319 "sfc_encapsulation": "mac"
324 "vl_id": "ext_datanet_net",
326 "cp_id": "m600_tunnel_cp",
328 "direction": "bidirectional",
329 "vnic_type": "normal",
331 "mac_address": "00-11-00-22-33-00",
332 "interface_name": "gei-0/4/0/13",
333 "ip_address": "191.167.100.5",
335 "sfc_encapsulation": "mac"
342 "cp_id": "m6000_data_in",
344 "direction": "bidirectional",
345 "vnic_type": "normal",
347 "mac_address": "11-22-33-22-11-41",
348 "interface_name": "gei-0/4/0/7",
349 "ip_address": "1.1.1.1",
351 "sfc_encapsulation": "mac",
357 "vl_id": "ext_mnet_net",
359 "cp_id": "m600_mnt_cp",
361 "direction": "bidirectional",
362 "vnic_type": "normal",
364 "mac_address": "00-11-00-22-33-11",
365 "interface_name": "gei-0/4/0/1",
366 "ip_address": "10.46.244.51",
368 "sfc_encapsulation": "mac",
374 "invariant_id": "vcpe_ns_sff_1",
376 "csarVersion": "v1.0",
378 "csarProvider": "ZTE",
382 "description": "vcpe_ns"
389 def test_ns_pkg_distribute_when_ns_exists(self):
390 NSDModel(id="1", nsd_id="2").save()
391 resp = self.client.post("/api/nslcm/v1/nspackage", {"csarId": "1"}, format='json')
392 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
393 self.assertEqual("failed", resp.data["status"])
394 self.assertEqual("NS CSAR(1) already exists.", resp.data["statusDescription"])
396 @mock.patch.object(restcall, 'call_req')
397 def test_ns_pkg_distribute_when_csar_not_exist(self, mock_call_req):
398 mock_call_req.return_value = [0, "[]", '200']
399 resp = self.client.post("/api/nslcm/v1/nspackage", {"csarId": "1"}, format='json')
400 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
401 self.assertEqual("failed", resp.data["status"])
402 self.assertEqual("Failed to query artifact(services,1) from sdc.", resp.data["statusDescription"])
404 @mock.patch.object(restcall, 'call_req')
405 @mock.patch.object(sdc, 'download_artifacts')
406 @mock.patch.object(toscaparser, 'parse_nsd')
407 def test_ns_pkg_distribute_when_nsd_already_exists(self,
408 mock_parse_nsd, mock_download_artifacts, mock_call_req):
409 mock_parse_nsd.return_value = json.JSONEncoder().encode(self.nsd_data)
410 mock_download_artifacts.return_value = "/home/vcpe.csar"
411 mock_call_req.return_value = [0, json.JSONEncoder().encode([{
413 "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/vcpe.csar"
415 NSDModel(id="2", nsd_id="VCPE_NS").save()
416 resp = self.client.post("/api/nslcm/v1/nspackage", {"csarId": "1"}, format='json')
417 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
418 self.assertEqual("failed", resp.data["status"])
419 self.assertEqual("NSD(VCPE_NS) already exists.", resp.data["statusDescription"])
421 @mock.patch.object(restcall, 'call_req')
422 @mock.patch.object(sdc, 'download_artifacts')
423 @mock.patch.object(toscaparser, 'parse_nsd')
424 def test_ns_pkg_distribute_when_nf_not_distributed(self,
425 mock_parse_nsd, mock_download_artifacts, mock_call_req):
426 mock_parse_nsd.return_value = json.JSONEncoder().encode(self.nsd_data)
427 mock_download_artifacts.return_value = "/home/vcpe.csar"
428 mock_call_req.return_value = [0, json.JSONEncoder().encode([{
430 "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/vcpe.csar"
432 resp = self.client.post("/api/nslcm/v1/nspackage", {"csarId": "1"}, format='json')
433 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
434 self.assertEqual("failed", resp.data["status"])
435 self.assertEqual("VNF package(vcpe_vfw_zte_1_0) is not distributed.", resp.data["statusDescription"])
437 @mock.patch.object(restcall, 'call_req')
438 @mock.patch.object(sdc, 'download_artifacts')
439 @mock.patch.object(toscaparser, 'parse_nsd')
440 def test_ns_pkg_distribute_when_successfully(self,
441 mock_parse_nsd, mock_download_artifacts, mock_call_req):
442 mock_parse_nsd.return_value = json.JSONEncoder().encode(self.nsd_data)
443 mock_download_artifacts.return_value = "/home/vcpe.csar"
444 mock_call_req.return_value = [0, json.JSONEncoder().encode([{
446 "toscaModelURL": "https://127.0.0.1:1234/sdc/v1/vcpe.csar"
448 NfPackageModel(uuid="1", nfpackageid="1", vnfdid="vcpe_vfw_zte_1_0").save()
449 resp = self.client.post("/api/nslcm/v1/nspackage", {"csarId": "1"}, format='json')
450 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
451 self.assertEqual("success", resp.data["status"])
452 self.assertEqual("CSAR(1) distributed successfully.", resp.data["statusDescription"])
454 ###############################################################################################################
456 def test_ns_pkg_normal_delete(self):
457 NSDModel(id="8", nsd_id="2").save()
458 resp = self.client.delete("/api/nslcm/v1/nspackage/8")
459 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
460 self.assertEqual("success", resp.data["status"])
461 self.assertEqual("Delete CSAR(8) successfully.", resp.data["statusDescription"])
463 def test_ns_pkg_force_delete(self):
464 NSInstModel(id="1", nspackage_id="8").save()
465 NSDModel(id="8", nsd_id="2").save()
466 resp = self.client.delete("/api/nslcm/v1/nspackage/8force")
467 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
468 self.assertEqual("success", resp.data["status"])
469 self.assertEqual("Delete CSAR(8) successfully.", resp.data["statusDescription"])
471 def test_ns_pkg_delete_when_pkg_in_using(self):
472 NSInstModel(id="1", nspackage_id="8").save()
473 NSDModel(id="8", nsd_id="2").save()
474 resp = self.client.delete("/api/nslcm/v1/nspackage/8")
475 self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
476 self.assertEqual("failed", resp.data["status"])
477 self.assertEqual("CSAR(8) is in using, cannot be deleted.", resp.data["statusDescription"])
479 def test_ns_pkg_get_all(self):
480 NSDModel(id="13", nsd_id="2", vendor="3", version="4").save()
482 resp = self.client.get("/api/nslcm/v1/nspackage")
483 self.assertEqual(resp.status_code, status.HTTP_200_OK)
484 self.assertEqual({"csars": [{"csarId":"13", "nsdId": "2"}]}, resp.data)
486 def test_ns_pkg_get_one(self):
487 NSDModel(id="14", nsd_id="2", vendor="3", version="4").save()
488 NSInstModel(id="1", nspackage_id="14", name="11").save()
490 resp = self.client.get("/api/nslcm/v1/nspackage/14")
491 self.assertEqual(resp.status_code, status.HTTP_200_OK)
492 self.assertEqual({"csarId": "14",
499 "nsInstanceId": "1", "nsInstanceName": "11"