1 # Copyright 2018 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.
17 from django.test import Client
18 from django.test import TestCase
19 from rest_framework import status
21 from lcm.pub.database.models import FPInstModel, CPInstModel, PortInstModel, NfInstModel
22 from lcm.pub.database.models import VNFFGInstModel
23 from lcm.pub.msapi import extsys
24 from lcm.pub.msapi import sdncdriver
25 from lcm.pub.utils import restcall
28 class TestSfc(TestCase):
30 self.client = Client()
31 FPInstModel.objects.filter().delete()
32 VNFFGInstModel.objects.filter().delete()
33 CPInstModel.objects.filter().delete()
34 PortInstModel.objects.filter().delete()
35 NfInstModel.objects.filter().delete()
37 self.save_vnffg_inst_data()
38 self.save_vnf_inst_data()
39 self.save_cp_inst_data()
40 self.save_port_inst_data()
41 self.save_fp_inst_data()
46 @mock.patch.object(restcall, 'call_req')
47 def test_sfc_instanciate(self, mock_call_req):
50 # "nsInstanceId": "ns_inst_1",
51 # "context": nsd_model,
53 # "sdnControllerId": "sdnControllerId_1"
55 # resp = self.client.post("/api/nslcm/v1/ns/sfc_instance", data, format='json')
56 # self.assertEqual(resp.status_code, status.HTTP_200_OK, resp.data)
58 @mock.patch.object(extsys, "get_sdn_controller_by_id")
59 @mock.patch.object(sdncdriver, "create_flow_classfier")
60 @mock.patch.object(restcall, 'call_req')
61 def test_create_flow_classfier(self, mock_call_req, mock_create_flow_classfier, mock_get_sdn_controller_by_id):
63 "fpinstid": "fp_inst_1",
64 "context": json.dumps(nsd_model)
66 mock_create_flow_classfier.return_value = [0, json.dumps({'id': '1'})]
67 mock_get_sdn_controller_by_id.return_value = json.loads('{"test":"test_name","url":"url_add"}')
68 resp = self.client.post("/api/nslcm/v1/ns/create_flow_classifier", data)
69 self.assertEqual(resp.status_code, status.HTTP_200_OK)
71 @mock.patch.object(extsys, "get_sdn_controller_by_id")
72 @mock.patch.object(sdncdriver, 'create_port_pair_group')
73 @mock.patch.object(sdncdriver, 'create_port_pair')
74 @mock.patch.object(restcall, 'call_req')
75 def test_create_port_pair_group(self, mock_call_req, mock_create_port_pair,
76 mock_create_port_pair_group, mock_get_sdn_controller_by_id):
78 "nsinstanceid": "ns_inst_1",
79 "fpinstid": "fp_inst_1",
80 "context": json.dumps(nsd_model)
82 mock_create_port_pair.return_value = [0, json.dumps({'id': '1'})]
83 mock_create_port_pair_group.return_value = [0, json.dumps({'id': '1'})]
84 mock_get_sdn_controller_by_id.return_value = json.loads('{"test":"test_name","url":"url_add"}')
85 resp = self.client.post("/api/nslcm/v1/ns/create_port_pair_group", data)
86 self.assertEqual(resp.status_code, status.HTTP_200_OK)
88 @mock.patch.object(extsys, "get_sdn_controller_by_id")
89 @mock.patch.object(sdncdriver, 'create_port_chain')
90 @mock.patch.object(restcall, 'call_req')
91 def test_create_port_chain(self, mock_call_req, mock_create_port_chain, mock_get_sdn_controller_by_id):
93 "nsinstanceid": "ns_inst_1",
94 "fpinstid": "fp_inst_1",
95 "context": json.dumps(nsd_model)
97 self.update_fp_inst_data()
98 mock_create_port_chain.return_value = [0, json.dumps({'id': '1'})]
99 mock_get_sdn_controller_by_id.return_value = json.loads('{"test":"test_name","url":"url_add"}')
100 resp = self.client.post("/api/nslcm/v1/ns/create_port_chain", data)
101 self.assertEqual(resp.status_code, status.HTTP_200_OK)
103 @mock.patch.object(restcall, 'call_req')
104 def test_create_sfc(self, mock_call_req):
107 # "nsInstanceId": "ns_inst_1",
108 # "context": json.dumps(nsd_model),
110 # 'fpinstid': str(uuid.uuid4()),
111 # "sdnControllerId": "sdnControllerId_1"
113 # resp = self.client.post("/api/nslcm/v1/ns/ns_sfcs", data, format='json')
114 # self.assertEqual(resp.status_code, status.HTTP_200_OK, resp.data)
116 def update_fp_inst_data(self):
117 FPInstModel.objects.filter(fpinstid="fp_inst_1").update(flowclassifiers="1",
118 portpairgroups=json.JSONEncoder().encode([{
123 def save_vnffg_inst_data(self):
125 vnffgdid="vnffg_id1",
126 vnffginstid="vnffg_inst_1",
127 nsinstid="ns_inst_1",
134 def save_cp_inst_data(self):
136 cpinstanceid="cp_inst_1",
139 ownerid="vnf_inst_1",
141 relatedport="port_inst_1"
145 cpinstanceid="cp_inst_2",
148 ownerid="vnf_inst_2",
150 relatedport="port_inst_2"
153 def save_fp_inst_data(self):
156 fpinstid="fp_inst_1",
157 nsinstid="ns_inst_1",
158 vnffginstid="vnffg_inst_1",
162 "dest_port_range": [80, 1024],
163 "source_port_range": [80, 1024],
164 "ip_protocol": "tcp",
165 "dest_ip_range": ["192.168.1.2", "192.168.1.100"],
166 "source_ip_range": ["192.168.1.2", "192.168.1.100"],
171 sdncontrollerid="sdn_controller_1"
177 fpinstid="fp_inst_2",
178 nsinstid="ns_inst_1",
179 vnffginstid="vnffg_inst_1",
183 "dest_port_range": [80, 1024],
184 "source_port_range": [80, 1024],
185 "ip_protocol": "tcp",
186 "dest_ip_range": ["192.168.1.2", "192.168.1.100"],
187 "source_ip_range": ["192.168.1.2", "192.168.1.100"],
192 sdncontrollerid="sdn_controller_1"
195 def save_sdnc_inst_data(self):
199 # sdncontrollerid="sdn_controller_1",
202 # url="192.168.0.1:8080",
206 # longitude="longitude",
207 # latitude="latitude"
210 def save_port_inst_data(self):
212 portid="port_inst_1",
213 networkid="network_inst_1",
214 subnetworkid="subnetwork_inst_1",
217 ipaddress="10.43.25.2",
218 macaddress="EC-F4-BB-20-43-F1"
222 portid="port_inst_2",
223 networkid="network_inst_1",
224 subnetworkid="subnetwork_inst_1",
227 ipaddress="10.43.25.3",
228 macaddress="EC-F4-BB-20-43-F2"
231 def save_vnf_inst_data(self):
233 nfinstid="vnf_inst_1",
234 ns_inst_id="ns_inst_1",
236 vnfd_model=json.dumps(vnfd_model_dict1)
241 nfinstid="vnf_inst_2",
243 ns_inst_id="ns_inst_1",
244 vnfd_model=json.dumps(vnfd_model_dict2)
262 'vdu_id': 'vdu_omm.001',
263 'image_file': 'opencos_sss_omm_img_release_20150723-1-disk1',
275 'support_scaling': False,
278 'storage_policy': '',
281 'availability_zone': '',
287 'inject_data_list': [
294 'local_affinity_antiaffinity_rule': {
297 'template_id': 'omm.001',
298 'manual_scale_select_vim': False
300 'description': 'singleommvm'
326 'support_scaling': False,
329 'storage_policy': '',
332 'availability_zone': '',
338 'inject_data_list': [
345 'local_affinity_antiaffinity_rule': {
349 'manual_scale_select_vim': False
351 'description': 'ompvm'
377 'support_scaling': False,
380 'storage_policy': '',
383 'availability_zone': '',
389 'inject_data_list': [
396 'local_affinity_antiaffinity_rule': {
400 'manual_scale_select_vim': False
402 'description': 'ompvm'
428 'support_scaling': False,
431 'storage_policy': '',
434 'availability_zone': '',
440 'inject_data_list': [
447 'local_affinity_antiaffinity_rule': {
451 'manual_scale_select_vim': False
453 'description': 'ompvm'
479 'support_scaling': False,
482 'storage_policy': '',
485 'availability_zone': '',
491 'inject_data_list': [
498 'local_affinity_antiaffinity_rule': {
502 'manual_scale_select_vim': False
504 'description': 'ppvm'
530 'support_scaling': False,
533 'storage_policy': '',
536 'availability_zone': '',
542 'inject_data_list': [
549 'local_affinity_antiaffinity_rule': {
553 'manual_scale_select_vim': False
555 'description': 'ppvm'
581 'support_scaling': False,
584 'storage_policy': '',
587 'availability_zone': '',
593 'inject_data_list': [
600 'local_affinity_antiaffinity_rule': {
604 'manual_scale_select_vim': False
606 'description': 'ppvm'
617 'policy_id': 'policy_scale_sss-vnf-template',
619 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'
628 'name': 'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
630 'disk_format': 'VMDK',
631 'file_url': './zte-cn-sss-main-image/OMM/opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
632 'container_type': 'vm',
634 'hypervisor_type': 'kvm'
636 'image_file_id': 'opencos_sss_omm_img_release_20150723-1-disk1'
643 'disk_format': 'VMDK',
644 'file_url': './zte-cn-sss-main-image/NE/sss.vmdk',
645 'container_type': 'vm',
647 'hypervisor_type': 'kvm'
649 'image_file_id': 'sss'
659 "mac_address": "00:d9:00:82:11:e1",
660 "ip_address": "10.43.25.2",
661 "ip_range_start": "192.168.1.20",
662 "ip_range_end": "192.168.1.29",
663 "sfc_encapsulation": ""
672 'version': 'v4.14.10',
673 'vmnumber_overquota_alarm': False,
676 'vnfd_version': 'V00000001',
678 'name': 'sss-vnf-template'
684 "key_name": "virtualLink1",
690 "key_name": "forwarder1",
694 "key_name": "forwarder2",
717 'vdu_id': 'vdu_omm.001',
718 'image_file': 'opencos_sss_omm_img_release_20150723-1-disk1',
730 'support_scaling': False,
733 'storage_policy': '',
736 'availability_zone': '',
742 'inject_data_list': [
749 'local_affinity_antiaffinity_rule': {
752 'template_id': 'omm.001',
753 'manual_scale_select_vim': False
755 'description': 'singleommvm'
781 'support_scaling': False,
784 'storage_policy': '',
787 'availability_zone': '',
793 'inject_data_list': [
800 'local_affinity_antiaffinity_rule': {
804 'manual_scale_select_vim': False
806 'description': 'ompvm'
832 'support_scaling': False,
835 'storage_policy': '',
838 'availability_zone': '',
844 'inject_data_list': [
851 'local_affinity_antiaffinity_rule': {
855 'manual_scale_select_vim': False
857 'description': 'ompvm'
883 'support_scaling': False,
886 'storage_policy': '',
889 'availability_zone': '',
895 'inject_data_list': [
902 'local_affinity_antiaffinity_rule': {
906 'manual_scale_select_vim': False
908 'description': 'ompvm'
934 'support_scaling': False,
937 'storage_policy': '',
940 'availability_zone': '',
946 'inject_data_list': [
953 'local_affinity_antiaffinity_rule': {
957 'manual_scale_select_vim': False
959 'description': 'ppvm'
985 'support_scaling': False,
988 'storage_policy': '',
991 'availability_zone': '',
997 'inject_data_list': [
1004 'local_affinity_antiaffinity_rule': {
1007 'template_id': '11',
1008 'manual_scale_select_vim': False
1010 'description': 'ppvm'
1013 'volumn_storages': [
1024 'image_file': 'sss',
1036 'support_scaling': False,
1039 'storage_policy': '',
1042 'availability_zone': '',
1048 'inject_data_list': [
1055 'local_affinity_antiaffinity_rule': {
1058 'template_id': '12',
1059 'manual_scale_select_vim': False
1061 'description': 'ppvm'
1064 'volumn_storages': [
1072 'policy_id': 'policy_scale_sss-vnf-template',
1074 'policy_file': '*-vnfd.zip/*-vnf-policy.xml'
1083 'name': 'opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1085 'disk_format': 'VMDK',
1086 'file_url': './zte-cn-sss-main-image/OMM/opencos_sss_omm_img_release_20150723-1-disk1.vmdk',
1087 'container_type': 'vm',
1089 'hypervisor_type': 'kvm'
1091 'image_file_id': 'opencos_sss_omm_img_release_20150723-1-disk1'
1098 'disk_format': 'VMDK',
1099 'file_url': './zte-cn-sss-main-image/NE/sss.vmdk',
1100 'container_type': 'vm',
1102 'hypervisor_type': 'kvm'
1104 'image_file_id': 'sss'
1114 "mac_address": "00:d9:00:82:11:e2",
1115 "ip_address": "10.43.25.3",
1116 "ip_range_start": "192.168.1.20",
1117 "ip_range_end": "192.168.1.29",
1118 "sfc_encapsulation": ""
1126 'domain_type': 'CN',
1127 'version': 'v4.14.10',
1128 'vmnumber_overquota_alarm': False,
1131 'vnfd_version': 'V00000001',
1132 'id': 'sss-vnf-template',
1138 "key_name": "virtualLink1",
1144 "key_name": "forwarder2",
1148 "key_name": "forwarder3",
1161 "description": "demo nsd",
1171 "type": "tosca.nodes.nfv.ext.VNF.FireWall",
1178 "vnfd_version": "1.1.0",
1180 "domain_type": "CN",
1184 "request_reclassification": False,
1186 "custom_properties": {
1192 "vnf_id1", "vnf_id2"
1196 "key_name": "virtualLink1",
1202 "type": "tosca.nodes.nfv.ext.VNF.FireWall",
1209 "vnfd_version": "1.1.0",
1211 "domain_type": "CN",
1215 "request_reclassification": False,
1217 "custom_properties": {
1223 "vnf_id1", "vnf_id2"
1227 "key_name": "virtualLink1",
1243 "request_reclassification": False,
1245 "management_address": "10.44.56.78"
1265 "key_name": "virtualLink1",
1277 "name": "umac_241_control",
1278 "network_id": "fgdhsj434hfjdfd",
1279 "network_name": "umac_control",
1282 "network_type": "vlan",
1283 "physical_network": "phynet01",
1284 "segmentation_id": "30",
1285 "vlan_transparent": False,
1287 "cidr": "192.168.199.0/24",
1289 "gateway_ip": "192.168.199.1",
1290 "dhcp_enabled": False,
1291 "dns_nameservers": ["192.168.0.4", "192.168.0.10"],
1292 "start_ip": "192.168.199.2",
1293 "end_ip": "192.168.199.254",
1296 "destination": "10.43.26.0/24",
1297 "nexthop": "10.41.23.1",
1302 "tenant": "tenantname",
1304 "vlan_transparent": False,
1314 "mac_address": "00:d9:00:82:11:e1",
1315 "ip_address": "192.168.1.21",
1316 "ip_range_start": "192.168.1.20",
1317 "ip_range_end": "192.168.1.29",
1318 "floating_ip_address": {
1319 "external_network": "extnet01",
1320 "ip_address": "10.43.53.23",
1322 "service_ip_address": "192.168.1.23",
1325 "vnic_type": "normal",
1326 "allowed_address_pairs": [
1328 "ip": "192.168.1.13",
1329 "mac": "00:f3:43:20:a2:a3"
1333 "macbond": "00:d9:00:82:11:d1",
1334 "sfc_encapsulation": "",
1342 "cp_id": "forwarder_brasDP_dcPort",
1345 "mac_address": "00:d9:00:82:14:e1",
1346 "ip_address": "192.168.1.24",
1347 "ip_range_start": "192.168.1.20",
1348 "ip_range_end": "192.168.1.29",
1349 "floating_ip_address": {
1350 "external_network": "extnet01",
1351 "ip_address": "10.43.53.23",
1353 "service_ip_address": "192.168.1.23",
1356 "vnic_type": "normal",
1357 "allowed_address_pairs": [
1359 "ip": "192.168.1.13",
1360 "mac": "00:f3:43:20:a2:a3"
1364 "macbond": "00:d9:00:82:11:d1",
1365 "sfc_encapsulation": "",
1372 "cp_id": "forwarder_brasDP_internetPort",
1375 "mac_address": "00:d9:00:82:15:e1",
1376 "ip_address": "192.168.1.25",
1377 "ip_range_start": "192.168.1.20",
1378 "ip_range_end": "192.168.1.29",
1379 "floating_ip_address": {
1380 "external_network": "extnet01",
1381 "ip_address": "10.43.53.23",
1383 "service_ip_address": "192.168.1.23",
1386 "vnic_type": "normal",
1387 "allowed_address_pairs": [
1389 "ip": "192.168.1.13",
1390 "mac": "00:f3:43:20:a2:a3"
1394 "macbond": "00:d9:00:82:11:d1",
1395 "sfc_encapsulation": "",
1412 "dest_port_range": [80, 1024],
1413 "source_port_range": [80, 1024],
1414 "ip_protocol": "tcp",
1415 "dest_ip_range": ["192.168.1.2", "192.168.1.100"],
1416 "source_ip_range": ["192.168.1.2", "192.168.1.100"],
1425 "node_name": "cpd_1",
1430 "node_name": "forwarder_brasDP_dcPort",
1435 "node_name": "vnf_1",
1436 "capability": "forwarder1",
1440 "node_name": "vnf_2",
1441 "capability": "forwarder2",
1445 "node_name": "forwarder_brasDP_dcPort",
1450 "node_name": "forwarder_brasDP_internetPort",
1463 "dest_port_range": [80, 1024],
1464 "source_port_range": [80, 1024],
1465 "ip_protocol": "tcp",
1466 "dest_ip_range": ["192.168.1.2", "192.168.1.100"],
1467 "source_ip_range": ["192.168.1.2", "192.168.1.100"],
1477 "node_name": "forwarder_brasDP_internetPort",
1482 "node_name": "forwarder_brasDP_dcPort",
1487 "node_name": "vnf_2",
1488 "capability": "forwarder2",
1497 "vnffg_id": "vnffg_id1",
1502 "number_of_endpoints": 7,
1503 "dependent_virtual_link": ["vldId1"],
1504 "connection_point": ["CP01", "CP02"],
1505 "constituent_vnfs": ["vnf_id1", "vnf_id2"],
1506 "constituent_pnfs": ["pnf1", "pnf2"],
1508 "members": ["fpd_1", "fpd_2"],
1517 "name": "server_group1",
1518 "affinity_antiaffinity": "anti-affinity",
1521 "members": ["vnf1", "vnf2"],
1528 "key_name": "virtualLink1",
1534 "key_name": "forwarder_brasDP_userPort",
1538 "key_name": "forwarder_brasDP_internetPort",
1542 "key_name": "forwarder_brasDP_dcPort",
1556 "policy_file": "Policies/ns1-policy.xml",
1558 "targets": ['pfu_vm'],
1566 "flavour_id": "flavour1",
1571 "flavour_id": "flavour1",
1572 "instances_minimum_number": 1,
1573 "instances_maximum_number": 4,
1574 "local_affinity_antiaffinity_rule": [
1576 "affinity_antiaffinity": "affinity",
1590 "bitrate_requirements": {
1595 "maximum_latency": "1 ms",
1596 "maximum_jitter": "10 ms",
1597 "maximum_packet_loss_ratio": 0.5
1601 "instantiation_levels": [
1608 "vnf_instantiation_level": "small",
1609 "instances_number": 1
1612 "scale_level_id": "scaleLevel1",
1615 "default_instantiation_level": "instLevel1",
1618 "id": "scaleLevel1",
1623 "vnf_instantiation_level": "small",
1624 "instances_number": 1
1629 "supported_operations": ["Scale", "Heal"],
1630 "affinity_antiaffinity_groups": [
1632 "group_id": "group1Id",
1633 "name": "groupName",
1634 "affinity_antiaffinity": "affinity",