From 85499ecb3034bd1a7ccf228ca0880456d4d46c71 Mon Sep 17 00:00:00 2001 From: lfourie Date: Tue, 28 Feb 2017 10:40:28 -0800 Subject: Add VNFFG release documentation Change-Id: Ib72fadba154e054c8c819f96d0ac5674fa7967fe Signed-off-by: lfourie --- networking_sfc/tests/__init__.py | 0 networking_sfc/tests/base.py | 134 - networking_sfc/tests/unit/__init__.py | 0 networking_sfc/tests/unit/cli/__init__.py | 0 .../tests/unit/cli/test_flow_classifier.py | 182 - networking_sfc/tests/unit/cli/test_port_chain.py | 186 - networking_sfc/tests/unit/cli/test_port_pair.py | 160 - .../tests/unit/cli/test_port_pair_group.py | 144 - networking_sfc/tests/unit/db/__init__.py | 0 .../tests/unit/db/test_flowclassifier_db.py | 677 ---- networking_sfc/tests/unit/db/test_sfc_db.py | 1490 -------- networking_sfc/tests/unit/extensions/__init__.py | 0 .../tests/unit/extensions/test_flowclassifier.py | 603 --- networking_sfc/tests/unit/extensions/test_sfc.py | 751 ---- networking_sfc/tests/unit/services/__init__.py | 0 .../tests/unit/services/flowclassifier/__init__.py | 0 .../services/flowclassifier/test_driver_manager.py | 158 - .../unit/services/flowclassifier/test_plugin.py | 168 - networking_sfc/tests/unit/services/sfc/__init__.py | 0 .../tests/unit/services/sfc/agent/__init__.py | 0 .../tests/unit/services/sfc/agent/test-agent.py | 4012 -------------------- .../tests/unit/services/sfc/common/__init__.py | 0 .../unit/services/sfc/common/test_ovs_ext_lib.py | 93 - .../tests/unit/services/sfc/drivers/__init__.py | 0 .../unit/services/sfc/drivers/ovs/__init__.py | 0 .../tests/unit/services/sfc/test_driver_manager.py | 325 -- .../tests/unit/services/sfc/test_plugin.py | 468 --- 27 files changed, 9551 deletions(-) delete mode 100644 networking_sfc/tests/__init__.py delete mode 100644 networking_sfc/tests/base.py delete mode 100644 networking_sfc/tests/unit/__init__.py delete mode 100644 networking_sfc/tests/unit/cli/__init__.py delete mode 100644 networking_sfc/tests/unit/cli/test_flow_classifier.py delete mode 100644 networking_sfc/tests/unit/cli/test_port_chain.py delete mode 100644 networking_sfc/tests/unit/cli/test_port_pair.py delete mode 100644 networking_sfc/tests/unit/cli/test_port_pair_group.py delete mode 100644 networking_sfc/tests/unit/db/__init__.py delete mode 100644 networking_sfc/tests/unit/db/test_flowclassifier_db.py delete mode 100644 networking_sfc/tests/unit/db/test_sfc_db.py delete mode 100644 networking_sfc/tests/unit/extensions/__init__.py delete mode 100644 networking_sfc/tests/unit/extensions/test_flowclassifier.py delete mode 100644 networking_sfc/tests/unit/extensions/test_sfc.py delete mode 100644 networking_sfc/tests/unit/services/__init__.py delete mode 100644 networking_sfc/tests/unit/services/flowclassifier/__init__.py delete mode 100644 networking_sfc/tests/unit/services/flowclassifier/test_driver_manager.py delete mode 100644 networking_sfc/tests/unit/services/flowclassifier/test_plugin.py delete mode 100644 networking_sfc/tests/unit/services/sfc/__init__.py delete mode 100644 networking_sfc/tests/unit/services/sfc/agent/__init__.py delete mode 100644 networking_sfc/tests/unit/services/sfc/agent/test-agent.py delete mode 100644 networking_sfc/tests/unit/services/sfc/common/__init__.py delete mode 100644 networking_sfc/tests/unit/services/sfc/common/test_ovs_ext_lib.py delete mode 100644 networking_sfc/tests/unit/services/sfc/drivers/__init__.py delete mode 100644 networking_sfc/tests/unit/services/sfc/drivers/ovs/__init__.py delete mode 100644 networking_sfc/tests/unit/services/sfc/test_driver_manager.py delete mode 100644 networking_sfc/tests/unit/services/sfc/test_plugin.py (limited to 'networking_sfc/tests') diff --git a/networking_sfc/tests/__init__.py b/networking_sfc/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/base.py b/networking_sfc/tests/base.py deleted file mode 100644 index 83fa3c9..0000000 --- a/networking_sfc/tests/base.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import contextlib -import mock -from oslo_utils import uuidutils - -from neutron.agent import securitygroups_rpc as sg_rpc -from neutron.api import extensions as api_ext -from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api as dhcp_rpc_log -from neutron.api.v2 import resource as api_res_log -from neutron.common import config as cfg -from neutron.extensions import vlantransparent as vlan_log -from neutron import manager -from neutron.notifiers import nova as nova_log -from neutron.plugins.ml2 import config -from neutron.plugins.ml2 import db as ml2_db -from neutron.plugins.ml2.drivers import type_flat -from neutron.plugins.ml2.drivers import type_local -from neutron.plugins.ml2.drivers import type_tunnel -from neutron.plugins.ml2.drivers import type_vlan -from neutron.plugins.ml2 import managers as ml2_manager -from neutron.plugins.ml2 import plugin as ml2_plugin -from neutron import quota as quota_log -from neutron.scheduler import dhcp_agent_scheduler as dhcp_agent_log - -from neutron.tests import base as n_base -from neutron.tests.unit.db import test_db_base_plugin_v2 as test_db_plugin - - -class BaseTestCase(n_base.BaseTestCase): - pass - - -class NeutronDbPluginV2TestCase(test_db_plugin.NeutronDbPluginV2TestCase): - def setUp(self, plugin=None, service_plugins=None, ext_mgr=None): - self._mock_unncessary_logging() - - if not plugin: - plugin = 'neutron.plugins.ml2.plugin.Ml2Plugin' - config.cfg.CONF.set_override('tenant_network_types', ['gre'], - group='ml2') - config.cfg.CONF.set_override( - 'tunnel_id_ranges', ['1:1000'], group='ml2_type_gre') - config.cfg.CONF.set_override( - 'mechanism_drivers', ['openvswitch'], group='ml2') - super(NeutronDbPluginV2TestCase, self).setUp( - ext_mgr=ext_mgr, - plugin=plugin, - service_plugins=service_plugins - ) - self._tenant_id = uuidutils.generate_uuid() - self._network = self._make_network( - self.fmt, 'net1', - True) - self._subnet = self._make_subnet( - self.fmt, self._network, gateway='10.0.0.1', - cidr='10.0.0.0/24', ip_version=4 - ) - - def _mock_unncessary_logging(self): - mock_log_sg_rpc_p = mock.patch.object(sg_rpc, 'LOG') - self.mock_log_sg_rpc = mock_log_sg_rpc_p.start() - - mock_log_api_ext_p = mock.patch.object(api_ext, 'LOG') - self.mock_log_api_ext = mock_log_api_ext_p.start() - - mock_log_dhcp_rpc_log_p = mock.patch.object(dhcp_rpc_log, 'LOG') - self.mock_log_dhcp_rpc_log = mock_log_dhcp_rpc_log_p.start() - - mock_log_dhcp_rpc_log_p = mock.patch.object(dhcp_rpc_log, 'LOG') - self.mock_log_dhcp_rpc_log = mock_log_dhcp_rpc_log_p.start() - - mock_log_api_res_log_p = mock.patch.object(api_res_log, 'LOG') - self.mock_log_api_res_log = mock_log_api_res_log_p.start() - - mock_log_cfg_p = mock.patch.object(cfg, 'LOG') - self.mock_log_cfg = mock_log_cfg_p.start() - - mock_log_vlan_log_p = mock.patch.object(vlan_log, 'LOG') - self.mock_log_vlan_log = mock_log_vlan_log_p.start() - - mock_log_manager_p = mock.patch.object(manager, 'LOG') - self.mock_log_manager = mock_log_manager_p.start() - - mock_log_nova_p = mock.patch.object(nova_log, 'LOG') - self.mock_log_nova = mock_log_nova_p.start() - - mock_log_ml2_db_p = mock.patch.object(ml2_db, 'LOG') - self.mock_log_ml2_db = mock_log_ml2_db_p.start() - - mock_log_ml2_manager_p = mock.patch.object(ml2_manager, 'LOG') - self.mock_log_ml2_manager = mock_log_ml2_manager_p.start() - - mock_log_plugin_p = mock.patch.object(ml2_plugin, 'LOG') - self.mock_log_plugin = mock_log_plugin_p.start() - - mock_log_type_flat_p = mock.patch.object(type_flat, 'LOG') - self.mock_log_type_flat = mock_log_type_flat_p.start() - - mock_log_type_local_p = mock.patch.object(type_local, 'LOG') - self.mock_log_type_local = mock_log_type_local_p.start() - - mock_log_type_tunnel_p = mock.patch.object(type_tunnel, 'LOG') - self.mock_log_type_tunnel = mock_log_type_tunnel_p.start() - - mock_log_type_vlan_p = mock.patch.object(type_vlan, 'LOG') - self.mock_log_type_vlan = mock_log_type_vlan_p.start() - - mock_log_quota_log_p = mock.patch.object(quota_log, 'LOG') - self.mock_log_quota_log = mock_log_quota_log_p.start() - - mock_log_dhcp_agent_log_p = mock.patch.object(dhcp_agent_log, 'LOG') - self.mock_log_dhcp_agent_log = mock_log_dhcp_agent_log_p.start() - - def tearDown(self): - super(NeutronDbPluginV2TestCase, self).tearDown() - - @contextlib.contextmanager - def port(self, fmt=None, **kwargs): - net_id = self._network['network']['id'] - port = self._make_port(fmt or self.fmt, net_id, **kwargs) - yield port diff --git a/networking_sfc/tests/unit/__init__.py b/networking_sfc/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/cli/__init__.py b/networking_sfc/tests/unit/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/cli/test_flow_classifier.py b/networking_sfc/tests/unit/cli/test_flow_classifier.py deleted file mode 100644 index 37c2142..0000000 --- a/networking_sfc/tests/unit/cli/test_flow_classifier.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright 2015 Huawei Technologies India Pvt. Ltd. -# All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import sys -import uuid - -import mock - -from neutronclient import shell -from neutronclient.tests.unit import test_cli20 - -from networking_sfc.cli import flow_classifier as fc - -source_port_UUID = str(uuid.uuid4()) -destination_port_UUID = str(uuid.uuid4()) - - -class CLITestV20FCExtensionJSON(test_cli20.CLITestV20Base): - def setUp(self): - self._mock_extension_loading() - super(CLITestV20FCExtensionJSON, self).setUp(plurals={}) - self.register_non_admin_status_resource('flow_classifier') - - def _create_patch(self, name, func=None): - patcher = mock.patch(name) - thing = patcher.start() - self.addCleanup(patcher.stop) - return thing - - def _mock_extension_loading(self): - ext_pkg = 'neutronclient.common.extension' - flow_classifier = self._create_patch(ext_pkg + - '._discover_via_entry_points') - flow_classifier.return_value = [("flow_classifier", fc)] - return flow_classifier - - def test_ext_cmd_loaded(self): - shell.NeutronShell('2.0') - ext_cmd = {'flow-classifier-list': fc.FlowClassifierList, - 'flow-classifier-create': fc.FlowClassifierCreate, - 'flow-classifier-update': fc.FlowClassifierUpdate, - 'flow-classifier-delete': fc.FlowClassifierDelete, - 'flow-classifier-show': fc.FlowClassifierShow} - self.assertDictContainsSubset(ext_cmd, shell.COMMANDS['2.0']) - - def test_create_flow_classifier_with_mandatory_params(self): - """create flow-classifier: flow1.""" - resource = 'flow_classifier' - cmd = fc.FlowClassifierCreate(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - name = 'flow1' - ethertype = 'IPv4' - args = [name, '--ethertype', ethertype] - position_names = ['name', 'ethertype'] - position_values = [name, ethertype] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_flow_classifier_with_all_params(self): - """create flow-classifier: flow1.""" - resource = 'flow_classifier' - cmd = fc.FlowClassifierCreate(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - name = 'flow1' - protocol_name = 'TCP' - ethertype = 'IPv4' - source_port = '0:65535' - source_port_min = 0 - source_port_max = 65535 - destination_port = '1:65534' - destination_port_min = 1 - destination_port_max = 65534 - source_ip = '192.168.1.0/24' - destination_ip = '192.168.2.0/24' - logical_source_port = '4a334cd4-fe9c-4fae-af4b-321c5e2eb051' - logical_destination_port = '1278dcd4-459f-62ed-754b-87fc5e4a6751' - description = 'my-desc' - l7_param = "url=my_url" - l7_param_expected = {"url": "my_url"} - args = [name, - '--protocol', protocol_name, - '--ethertype', ethertype, - '--source-port', source_port, - '--destination-port', destination_port, - '--source-ip-prefix', source_ip, - '--destination-ip-prefix', destination_ip, - '--logical-source-port', logical_source_port, - '--logical-destination-port', logical_destination_port, - '--description', description, - '--l7-parameters', l7_param] - position_names = ['name', 'protocol', 'ethertype', - 'source_port_range_min', 'source_port_range_max', - 'destination_port_range_min', - 'destination_port_range_max', - 'source_ip_prefix', 'destination_ip_prefix', - 'logical_source_port', 'logical_destination_port', - 'description', 'l7_parameters'] - position_values = [name, protocol_name, ethertype, - source_port_min, source_port_max, - destination_port_min, destination_port_max, - source_ip, destination_ip, logical_source_port, - logical_destination_port, description, - l7_param_expected] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_list_flow_classifier(self): - """List available flow-classifiers.""" - resources = "flow_classifiers" - cmd = fc.FlowClassifierList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, True) - - def test_list_flow_classifier_sort(self): - """flow_classifier-list --sort-key name --sort-key id --sort-key asc - - --sort-key desc - """ - resources = "flow_classifiers" - cmd = fc.FlowClassifierList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, - sort_key=["name", "id"], - sort_dir=["asc", "desc"]) - - def test_list_flow_classifier_limit(self): - """flow-classifier-list -P.""" - resources = "flow_classifiers" - cmd = fc.FlowClassifierList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, page_size=1000) - - def test_show_flow_classifier_id(self): - """flow-classifier-show test_id.""" - resource = 'flow_classifier' - cmd = fc.FlowClassifierShow(test_cli20.MyApp(sys.stdout), None) - args = ['--fields', 'id', self.test_id] - self._test_show_resource(resource, cmd, self.test_id, args, ['id']) - - def test_show_flow_classifier_id_name(self): - """flow-classifier-show .""" - resource = 'flow_classifier' - cmd = fc.FlowClassifierShow(test_cli20.MyApp(sys.stdout), None) - args = ['--fields', 'id', '--fields', 'name', self.test_id] - self._test_show_resource(resource, cmd, self.test_id, - args, ['id', 'name']) - - def test_update_flow_classifier_description(self): - """flow-classifier-update myid --name newname.""" - resource = 'flow_classifier' - cmd = fc.FlowClassifierUpdate(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid, '--description', 'flow_classifier1', '--description', - 'flow_classifier2'] - updatefields = {'description': 'flow_classifier2'} - self._test_update_resource(resource, cmd, myid, args, updatefields) - - def test_update_flow_classifier_name(self): - """flow-classifier-update myid --protocol any.""" - resource = 'flow_classifier' - cmd = fc.FlowClassifierUpdate(test_cli20.MyApp(sys.stdout), None) - self._test_update_resource(resource, cmd, 'myid', - ['myid', '--name', 'myname'], - {'name': 'myname'}) - - def test_delete_flow_classifer(self): - """flow-classifier-delete my-id.""" - resource = 'flow_classifier' - cmd = fc.FlowClassifierDelete(test_cli20.MyApp(sys.stdout), None) - my_id = 'myid1' - args = [my_id] - self._test_delete_resource(resource, cmd, my_id, args) diff --git a/networking_sfc/tests/unit/cli/test_port_chain.py b/networking_sfc/tests/unit/cli/test_port_chain.py deleted file mode 100644 index 0d834bd..0000000 --- a/networking_sfc/tests/unit/cli/test_port_chain.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright 2015 Huawei Technologies India Pvt. Ltd. -# All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import sys -import uuid - -import mock - -from neutronclient import shell -from neutronclient.tests.unit import test_cli20 - -from networking_sfc.cli import port_chain as pc - -FAKE_port_pair_group1_UUID = str(uuid.uuid4()) -FAKE_port_pair_group2_UUID = str(uuid.uuid4()) -FAKE_FC1_UUID = str(uuid.uuid4()) -FAKE_FC2_UUID = str(uuid.uuid4()) -FAKE_PARAM1_UUID = str(uuid.uuid4()) -FAKE_PARAM2_UUID = str(uuid.uuid4()) - - -class CLITestV20PortChainExtensionJSON(test_cli20.CLITestV20Base): - def setUp(self): - self._mock_extension_loading() - super(CLITestV20PortChainExtensionJSON, self).setUp() - self.register_non_admin_status_resource('port_chain') - - def _create_patch(self, name, func=None): - patcher = mock.patch(name) - thing = patcher.start() - self.addCleanup(patcher.stop) - return thing - - def _mock_extension_loading(self): - ext_pkg = 'neutronclient.common.extension' - port_chain = self._create_patch(ext_pkg + - '._discover_via_entry_points') - port_chain.return_value = [("port_chain", pc)] - return port_chain - - def test_ext_cmd_loaded(self): - shell.NeutronShell('2.0') - ext_cmd = {'port-chain-list': pc.PortChainList, - 'port-chain-create': pc.PortChainCreate, - 'port-chain-update': pc.PortChainUpdate, - 'port-chain-delete': pc.PortChainDelete, - 'port-chain-show': pc.PortChainShow} - self.assertDictContainsSubset(ext_cmd, shell.COMMANDS['2.0']) - - def test_create_port_chain_with_mandatory_param(self): - """Create port_chain: myname.""" - resource = 'port_chain' - cmd = pc.PortChainCreate(test_cli20.MyApp(sys.stdout), - None) - name = 'myname' - myid = 'myid' - args = [name, '--port-pair-group', FAKE_port_pair_group1_UUID] - position_names = ['name', 'port_pair_groups'] - position_values = [name, [FAKE_port_pair_group1_UUID]] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_port_chain_with_multiple_port_pair_group(self): - """Create port_chain: myname.""" - resource = 'port_chain' - cmd = pc.PortChainCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - args = [name, '--port-pair-group', FAKE_port_pair_group1_UUID, - '--port-pair-group', FAKE_port_pair_group2_UUID] - position_names = ['name', 'port_pair_groups'] - position_values = [name, [FAKE_port_pair_group1_UUID, - FAKE_port_pair_group2_UUID]] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_port_chain_with_all_params(self): - """Create port_chain: myname.""" - resource = 'port_chain' - cmd = pc.PortChainCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - desc = 'check port chain cli' - chain_parameter = "correlation=mpls" - chain_parameter_expected = {"correlation": "mpls"} - args = [name, '--description', desc, '--port-pair-group', - FAKE_port_pair_group1_UUID, '--flow-classifier', - FAKE_FC1_UUID, '--chain-parameters', chain_parameter] - position_names = ['name', 'description', 'port_pair_groups', - 'flow_classifiers', 'chain_parameters'] - position_values = [name, desc, [FAKE_port_pair_group1_UUID], - [FAKE_FC1_UUID], chain_parameter_expected] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_port_chain_with_single_classifier(self): - """Create port_chain: myname.""" - resource = 'port_chain' - cmd = pc.PortChainCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - args = [name, '--port-pair-group', FAKE_port_pair_group1_UUID, - '--flow-classifier', FAKE_FC1_UUID] - position_names = ['name', 'port_pair_groups', 'flow_classifiers'] - position_values = [name, [FAKE_port_pair_group1_UUID], [FAKE_FC1_UUID]] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_port_chain_with_multiple_classifiers(self): - """Create port_chain: myname.""" - resource = 'port_chain' - cmd = pc.PortChainCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - args = [name, '--port-pair-group', FAKE_port_pair_group1_UUID, - '--flow-classifier', FAKE_FC1_UUID, - '--flow-classifier', FAKE_FC2_UUID] - position_names = ['name', 'port_pair_groups', 'flow_classifiers'] - position_values = [name, [FAKE_port_pair_group1_UUID], [FAKE_FC1_UUID, - FAKE_FC2_UUID]] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_update_port_chain(self): - """Update port_chain: myid --name myname.""" - resource = 'port_chain' - cmd = pc.PortChainUpdate(test_cli20.MyApp(sys.stdout), None) - self._test_update_resource(resource, cmd, 'myid', - ['myid', '--name', 'myname'], - {'name': 'myname'}) - - def test_update_port_chain_with_no_flow_classifier(self): - """Update port_chain: myid --name myname --no-flow-classifier None.""" - resource = 'port_chain' - cmd = pc.PortChainUpdate(test_cli20.MyApp(sys.stdout), None) - self._test_update_resource(resource, cmd, 'myid', - ['myid', '--name', 'myname', - '--no-flow-classifier'], - {'name': 'myname', - 'flow_classifiers': []}) - - def test_delete_port_chain(self): - """Delete port-chain: myid.""" - resource = 'port_chain' - cmd = pc.PortChainDelete(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid] - self._test_delete_resource(resource, cmd, myid, args) - - def test_list_port_chain(self): - """List port_chain.""" - resources = 'port_chains' - cmd = pc.PortChainList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, True) - - def test_list_port_chains_sort(self): - """List port_chains: --sort-key name --sort-key id --sort-key asc - - --sort-key desc - """ - resources = "port_chains" - cmd = pc.PortChainList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, - sort_key=["name", "id"], - sort_dir=["asc", "desc"]) - - def test_show_port_chain(self): - """Show port-chain: --fields id --fields name myid.""" - resource = 'port_chain' - cmd = pc.PortChainShow(test_cli20.MyApp(sys.stdout), None) - args = ['--fields', 'id', '--fields', 'name', self.test_id] - self._test_show_resource(resource, cmd, self.test_id, - args, ['id', 'name']) diff --git a/networking_sfc/tests/unit/cli/test_port_pair.py b/networking_sfc/tests/unit/cli/test_port_pair.py deleted file mode 100644 index 9a302e2..0000000 --- a/networking_sfc/tests/unit/cli/test_port_pair.py +++ /dev/null @@ -1,160 +0,0 @@ -# Copyright 2015 Huawei Technologies India Pvt. Ltd. -# All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import sys -import uuid - -import mock - -from neutronclient import shell -from neutronclient.tests.unit import test_cli20 - -from networking_sfc.cli import port_pair as pp - -ingress_port_UUID = str(uuid.uuid4()) -egress_port_UUID = str(uuid.uuid4()) - - -class CLITestV20PortPairExtensionJSON(test_cli20.CLITestV20Base): - def setUp(self): - self._mock_extension_loading() - super(CLITestV20PortPairExtensionJSON, self).setUp() - self.register_non_admin_status_resource('port_pair') - - def _create_patch(self, name, func=None): - patcher = mock.patch(name) - thing = patcher.start() - self.addCleanup(patcher.stop) - return thing - - def _mock_extension_loading(self): - ext_pkg = 'neutronclient.common.extension' - port_pair = self._create_patch(ext_pkg + - '._discover_via_entry_points') - port_pair.return_value = [("port_pair", pp)] - return port_pair - - def test_ext_cmd_loaded(self): - shell.NeutronShell('2.0') - ext_cmd = {'port-pair-list': pp.PortPairList, - 'port-pair-create': pp.PortPairCreate, - 'port-pair-update': pp.PortPairUpdate, - 'port-pair-delete': pp.PortPairDelete, - 'port-pair-show': pp.PortPairShow} - self.assertDictContainsSubset(ext_cmd, shell.COMMANDS['2.0']) - - def test_create_port_pair_with_mandatory_param(self): - """Create port_pair: myname.""" - resource = 'port_pair' - cmd = pp.PortPairCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - args = [name, '--ingress', ingress_port_UUID, - '--egress', egress_port_UUID] - position_names = ['name', 'ingress', 'egress'] - position_values = [name, ingress_port_UUID, egress_port_UUID] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_port_group_with_bidirectional_port(self): - """Create port_pair: myname with bidirectional port.""" - resource = 'port_pair' - cmd = pp.PortPairCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - args = [name, '--ingress', ingress_port_UUID, - '--egress', ingress_port_UUID] - position_names = ['name', 'ingress', 'egress'] - position_values = [name, ingress_port_UUID, ingress_port_UUID] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_port_pair_with_all_param(self): - """Create port_pair: myname with all parameter""" - resource = 'port_pair' - cmd = pp.PortPairCreate(test_cli20.MyApp(sys.stdout), - None) - name = 'myname' - myid = 'myid' - desc = "my_port_pair" - service_fn_param = 'correlation=None' - service_fn_param_exp = {"correlation": "None"} - args = [name, '--ingress', ingress_port_UUID, - '--egress', egress_port_UUID, '--description', desc, - '--service-function-parameters', service_fn_param] - position_names = ['name', 'ingress', 'egress', 'description', - 'service_function_parameters'] - position_values = [name, ingress_port_UUID, egress_port_UUID, desc, - service_fn_param_exp] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_update_port_pair_description(self): - """Update port_pair: myid --name myname.""" - resource = 'port_pair' - desc1 = "My_New_Port_Pair" - cmd = pp.PortPairUpdate(test_cli20.MyApp(sys.stdout), None) - self._test_update_resource(resource, cmd, 'myid', - ['myid', '--description', desc1], - {'description': desc1}) - - def test_update_port_pair_name(self): - """Update port_pair: myid --name myname.""" - resource = 'port_pair' - my_name = "My_New_Port_Pair" - cmd = pp.PortPairUpdate(test_cli20.MyApp(sys.stdout), None) - self._test_update_resource(resource, cmd, 'myid', - ['myid', '--name', my_name], - {'name': my_name}) - - def test_delete_port_pair(self): - """Delete port-pair: myid.""" - resource = 'port_pair' - cmd = pp.PortPairDelete(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid] - self._test_delete_resource(resource, cmd, myid, args) - - def test_list_port_pair(self): - """List port_pairs.""" - resources = 'port_pairs' - cmd = pp.PortPairList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, True) - - def test_list_port_pair_limit(self): - """size (1000) limited list: port-pair -P.""" - resources = "port_pairs" - cmd = pp.PortPairList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, page_size=1000) - - def test_list_port_pairs_sort(self): - """List port_pairs: --sort-key name --sort-key id --sort-key asc - - --sort-key desc - """ - resources = "port_pairs" - cmd = pp.PortPairList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, - sort_key=["name", "id"], - sort_dir=["asc", "desc"]) - - def test_show_port_pair(self): - """Show port-pairs: --fields id --fields name myid.""" - resource = 'port_pair' - cmd = pp.PortPairShow(test_cli20.MyApp(sys.stdout), None) - args = ['--fields', 'id', '--fields', 'name', self.test_id] - self._test_show_resource(resource, cmd, self.test_id, - args, ['id', 'name']) diff --git a/networking_sfc/tests/unit/cli/test_port_pair_group.py b/networking_sfc/tests/unit/cli/test_port_pair_group.py deleted file mode 100644 index f610ef0..0000000 --- a/networking_sfc/tests/unit/cli/test_port_pair_group.py +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright 2015 Huawei Technologies India Pvt. Ltd. -# All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -import sys -import uuid - -import mock - -from neutronclient import shell -from neutronclient.tests.unit import test_cli20 - -from networking_sfc.cli import port_pair_group as pg - -pp1 = str(uuid.uuid4()) -pp2 = str(uuid.uuid4()) -pp3 = str(uuid.uuid4()) -pp4 = str(uuid.uuid4()) - - -class CLITestV20PortGroupExtensionJSON(test_cli20.CLITestV20Base): - def setUp(self): - self._mock_extension_loading() - super(CLITestV20PortGroupExtensionJSON, self).setUp() - self.register_non_admin_status_resource('port_pair_group') - - def _create_patch(self, name, func=None): - patcher = mock.patch(name) - thing = patcher.start() - self.addCleanup(patcher.stop) - return thing - - def _mock_extension_loading(self): - ext_pkg = 'neutronclient.common.extension' - port_pair_group = self._create_patch(ext_pkg + - '._discover_via_entry_points') - port_pair_group.return_value = [("port_pair_group", pg)] - return port_pair_group - - def test_ext_cmd_loaded(self): - shell.NeutronShell('2.0') - ext_cmd = {'port-pair-group-list': pg.PortPairGroupList, - 'port-pair-group-create': pg.PortPairGroupCreate, - 'port-pair-group-update': pg.PortPairGroupUpdate, - 'port-pair-group-delete': pg.PortPairGroupDelete, - 'port-pair-group-show': pg.PortPairGroupShow} - self.assertDictContainsSubset(ext_cmd, shell.COMMANDS['2.0']) - - def test_create_port_pair_group_with_mandatory_args(self): - """Create port_pair_group: myname.""" - resource = 'port_pair_group' - cmd = pg.PortPairGroupCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - args = [name, '--port-pair', pp1] - position_names = ['name', 'port_pairs'] - position_values = [name, [pp1]] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_create_port_pair_group_with_ingress_egress_port_group(self): - """Create port_pair_group: myname with multiple port pairs""" - resource = 'port_pair_group' - cmd = pg.PortPairGroupCreate(test_cli20.MyApp(sys.stdout), None) - name = 'myname' - myid = 'myid' - args = [name, '--port-pair', pp1, '--port-pair', pp2] - position_names = ['name', 'port_pairs'] - position_values = [name, [pp1, pp2]] - self._test_create_resource(resource, cmd, name, myid, args, - position_names, position_values) - - def test_delete_port_pair_group(self): - """Delete port_pair_group: myid.""" - resource = 'port_pair_group' - cmd = pg.PortPairGroupDelete(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid] - self._test_delete_resource(resource, cmd, myid, args) - - def test_update_port_group_only_port_pair(self): - """Update port_pair_group""" - resource = 'port_pair_group' - cmd = pg.PortPairGroupUpdate(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid, '--port-pair', pp1, - '--port-pair', pp2] - updatefields = {'port_pairs': [pp1, pp2]} - self._test_update_resource(resource, cmd, myid, args, updatefields) - - def test_update_port_group_with_all_desc(self): - """Update port_pair_group and description""" - resource = 'port_pair_group' - cmd = pg.PortPairGroupUpdate(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid, '--port-pair', pp1, - '--port-pair', pp2, '--description', 'my_port_group', - '--description', 'my_port_pair_group'] - updatefields = {'port_pairs': [pp1, pp2], - 'description': 'my_port_pair_group'} - self._test_update_resource(resource, cmd, myid, args, updatefields) - - def test_list_port_pair_group(self): - """List port_pair_group.""" - resources = 'port_pair_groups' - cmd = pg.PortPairGroupList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, True) - - def test_list_port_pair_group_limit(self): - """size (1000) limited list: port-pair-group -P.""" - resources = "port_pair_groups" - cmd = pg.PortPairGroupList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, page_size=1000) - - def test_list_port_group_sort(self): - """List port_pair_group: --sort-key name --sort-key id --sort-key asc - - --sort-key desc - """ - resources = "port_pair_groups" - cmd = pg.PortPairGroupList(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(resources, cmd, - sort_key=["name", "id"], - sort_dir=["asc", "desc"]) - - def test_show_port_group(self): - """Show port-chain: --fields id --fields name myid.""" - resource = 'port_pair_group' - cmd = pg.PortPairGroupShow(test_cli20.MyApp(sys.stdout), None) - args = ['--fields', 'id', '--fields', 'name', self.test_id] - self._test_show_resource(resource, cmd, self.test_id, - args, ['id', 'name']) diff --git a/networking_sfc/tests/unit/db/__init__.py b/networking_sfc/tests/unit/db/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/db/test_flowclassifier_db.py b/networking_sfc/tests/unit/db/test_flowclassifier_db.py deleted file mode 100644 index 36c9af8..0000000 --- a/networking_sfc/tests/unit/db/test_flowclassifier_db.py +++ /dev/null @@ -1,677 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import contextlib -import mock -import six -import webob.exc - -from oslo_config import cfg -from oslo_utils import importutils -from oslo_utils import uuidutils - -from neutron.api import extensions as api_ext -from neutron.common import config -from neutron.common import constants as const -import neutron.extensions as nextensions - -from networking_sfc.db import flowclassifier_db as fdb -from networking_sfc import extensions -from networking_sfc.extensions import flowclassifier as fc_ext -from networking_sfc.tests import base - - -DB_FLOWCLASSIFIER_PLUGIN_CLASS = ( - "networking_sfc.db.flowclassifier_db.FlowClassifierDbPlugin" -) -extensions_path = ':'.join(extensions.__path__ + nextensions.__path__) - - -class FlowClassifierDbPluginTestCaseBase(base.BaseTestCase): - def _create_flow_classifier( - self, fmt, flow_classifier=None, expected_res_status=None, **kwargs - ): - ctx = kwargs.get('context', None) - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'flow_classifier': flow_classifier or {}} - if ctx is None: - data['flow_classifier'].update({'tenant_id': tenant_id}) - req = self.new_create_request( - 'flow_classifiers', data, fmt, context=ctx - ) - res = req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(res.status_int, expected_res_status) - return res - - @contextlib.contextmanager - def flow_classifier( - self, fmt=None, flow_classifier=None, do_delete=True, **kwargs - ): - if not fmt: - fmt = self.fmt - res = self._create_flow_classifier(fmt, flow_classifier, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - flow_classifier = self.deserialize(fmt or self.fmt, res) - yield flow_classifier - if do_delete: - self._delete('flow_classifiers', - flow_classifier['flow_classifier']['id']) - - def _get_expected_flow_classifier(self, flow_classifier): - expected_flow_classifier = { - 'name': flow_classifier.get('name') or '', - 'description': flow_classifier.get('description') or '', - 'source_port_range_min': flow_classifier.get( - 'source_port_range_min'), - 'source_port_range_max': flow_classifier.get( - 'source_port_range_max'), - 'destination_port_range_min': flow_classifier.get( - 'destination_port_range_min'), - 'destination_port_range_max': flow_classifier.get( - 'destination_port_range_max'), - 'ethertype': flow_classifier.get( - 'ethertype') or 'IPv4', - 'protocol': flow_classifier.get( - 'protocol'), - 'l7_parameters': flow_classifier.get( - 'l7_parameters') or {} - } - if ( - 'source_ip_prefix' in flow_classifier and - flow_classifier['source_ip_prefix'] - ): - expected_flow_classifier['source_ip_prefix'] = ( - flow_classifier['source_ip_prefix']) - if ( - 'destination_ip_prefix' in flow_classifier and - flow_classifier['destination_ip_prefix'] - ): - expected_flow_classifier['destination_ip_prefix'] = ( - flow_classifier['destination_ip_prefix']) - return expected_flow_classifier - - def _test_create_flow_classifier( - self, flow_classifier, expected_flow_classifier=None - ): - if expected_flow_classifier is None: - expected_flow_classifier = self._get_expected_flow_classifier( - flow_classifier) - with self.flow_classifier(flow_classifier=flow_classifier) as fc: - for k, v in six.iteritems(expected_flow_classifier): - self.assertIn(k, fc['flow_classifier']) - self.assertEqual(fc['flow_classifier'][k], v) - - -class FlowClassifierDbPluginTestCase( - base.NeutronDbPluginV2TestCase, - FlowClassifierDbPluginTestCaseBase -): - resource_prefix_map = dict( - (k, fc_ext.FLOW_CLASSIFIER_PREFIX) - for k in fc_ext.RESOURCE_ATTRIBUTE_MAP.keys() - ) - - def setUp(self, core_plugin=None, flowclassifier_plugin=None, - ext_mgr=None): - mock_log_p = mock.patch.object(fdb, 'LOG') - self.mock_log = mock_log_p.start() - cfg.CONF.register_opts(fc_ext.flow_classifier_quota_opts, 'QUOTAS') - if not flowclassifier_plugin: - flowclassifier_plugin = DB_FLOWCLASSIFIER_PLUGIN_CLASS - service_plugins = { - fc_ext.FLOW_CLASSIFIER_EXT: flowclassifier_plugin - } - fdb.FlowClassifierDbPlugin.supported_extension_aliases = [ - fc_ext.FLOW_CLASSIFIER_EXT] - fdb.FlowClassifierDbPlugin.path_prefix = ( - fc_ext.FLOW_CLASSIFIER_PREFIX - ) - super(FlowClassifierDbPluginTestCase, self).setUp( - ext_mgr=ext_mgr, - plugin=core_plugin, - service_plugins=service_plugins - ) - if not ext_mgr: - self.flowclassifier_plugin = importutils.import_object( - flowclassifier_plugin) - ext_mgr = api_ext.PluginAwareExtensionManager( - extensions_path, - {fc_ext.FLOW_CLASSIFIER_EXT: self.flowclassifier_plugin} - ) - app = config.load_paste_app('extensions_test_app') - self.ext_api = api_ext.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - def test_create_flow_classifier(self): - self._test_create_flow_classifier({}) - - def test_quota_create_flow_classifier(self): - cfg.CONF.set_override('quota_flow_classifier', 3, group='QUOTAS') - self._create_flow_classifier(self.fmt, {}, expected_res_status=201) - self._create_flow_classifier(self.fmt, {}, expected_res_status=201) - self._create_flow_classifier(self.fmt, {}, expected_res_status=201) - self._create_flow_classifier(self.fmt, {}, expected_res_status=409) - - def test_create_flow_classifier_with_all_fields(self): - self._test_create_flow_classifier({ - 'name': 'test1', - 'ethertype': const.IPv4, - 'protocol': const.PROTO_NAME_TCP, - 'source_port_range_min': 100, - 'source_port_range_max': 200, - 'destination_port_range_min': 101, - 'destination_port_range_max': 201, - 'source_ip_prefix': '10.100.0.0/16', - 'destination_ip_prefix': '10.200.0.0/16', - 'logical_source_port': None, - 'logical_destination_port': None, - 'l7_parameters': {} - }) - - def test_create_flow_classifier_with_all_supported_ethertype(self): - self._test_create_flow_classifier({ - 'ethertype': None - }) - self._test_create_flow_classifier({ - 'ethertype': 'IPv4' - }) - self._test_create_flow_classifier({ - 'ethertype': 'IPv6' - }) - - def test_create_flow_classifier_with_invalid_ethertype(self): - self._create_flow_classifier( - self.fmt, { - 'ethertype': 'unsupported', - }, - expected_res_status=400 - ) - - def test_create_flow_classifier_with_all_supported_protocol(self): - self._test_create_flow_classifier({ - 'protocol': None - }) - self._test_create_flow_classifier({ - 'protocol': const.PROTO_NAME_TCP - }) - self._test_create_flow_classifier({ - 'protocol': const.PROTO_NAME_UDP - }) - self._test_create_flow_classifier({ - 'protocol': const.PROTO_NAME_ICMP - }) - - def test_create_flow_classifier_with_invalid_protocol(self): - self._create_flow_classifier( - self.fmt, { - 'protocol': 'unsupported', - }, - expected_res_status=400 - ) - - def test_create_flow_classifier_with_all_supported_port_protocol(self): - self._test_create_flow_classifier({ - 'source_port_range_min': None, - 'source_port_range_max': None, - 'destination_port_range_min': None, - 'destination_port_range_max': None - }) - self._test_create_flow_classifier({ - 'source_port_range_min': 100, - 'source_port_range_max': 200, - 'destination_port_range_min': 100, - 'destination_port_range_max': 200, - 'protocol': const.PROTO_NAME_TCP - }) - self._test_create_flow_classifier({ - 'source_port_range_min': 100, - 'source_port_range_max': 100, - 'destination_port_range_min': 100, - 'destination_port_range_max': 100, - 'protocol': const.PROTO_NAME_TCP - }) - self._test_create_flow_classifier({ - 'source_port_range_min': '100', - 'source_port_range_max': '200', - 'destination_port_range_min': '100', - 'destination_port_range_max': '200', - 'protocol': const.PROTO_NAME_UDP - }, { - 'source_port_range_min': 100, - 'source_port_range_max': 200, - 'destination_port_range_min': 100, - 'destination_port_range_max': 200, - 'protocol': const.PROTO_NAME_UDP - }) - - def test_create_flow_classifier_with_invalid__port_protocol(self): - self._create_flow_classifier( - self.fmt, { - 'source_port_range_min': 'abc', - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_max': 'abc', - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_min': 100, - 'source_port_range_max': 99, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_min': 65536, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_max': 65536, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_min': -1, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_max': -1, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_min': 'abc', - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_max': 'abc', - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_min': 100, - 'destination_port_range_max': 99, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_min': 65536, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_max': 65536, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_min': -1, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_max': -1, - 'protocol': const.PROTO_NAME_TCP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_min': 100 - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_max': 100 - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_min': 100, - 'source_port_range_max': 200 - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_port_range_min': 100, - 'source_port_range_max': 200, - 'protocol': const.PROTO_NAME_ICMP - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_min': 100 - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_max': 100 - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_min': 100, - 'destination_port_range_max': 200 - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_port_range_min': 100, - 'destination_port_range_max': 200, - 'protocol': const.PROTO_NAME_ICMP - }, - expected_res_status=400 - ) - - def test_create_flow_classifier_with_all_supported_ip_prefix(self): - self._test_create_flow_classifier({ - 'source_ip_prefix': None, - 'destination_ip_prefix': None - }) - self._test_create_flow_classifier({ - 'source_ip_prefix': '10.0.0.0/8', - 'destination_ip_prefix': '10.0.0.0/8' - }) - - def test_create_flow_classifier_with_invalid_ip_prefix(self): - self._create_flow_classifier( - self.fmt, { - 'source_ip_prefix': '10.0.0.0/34' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_ip_prefix': '10.0.0.0.0/8' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_ip_prefix': '256.0.0.0/8' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'source_ip_prefix': '10.0.0.0' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_ip_prefix': '10.0.0.0/34' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_ip_prefix': '10.0.0.0.0/8' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_ip_prefix': '256.0.0.0/8' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'destination_ip_prefix': '10.0.0.0' - }, - expected_res_status=400 - ) - - def test_create_flow_classifier_with_all_supported_l7_parameters(self): - self._test_create_flow_classifier({ - 'l7_parameters': None - }) - self._test_create_flow_classifier({ - 'l7_parameters': {} - }) - - def test_create_flow_classifier_with_invalid_l7_parameters(self): - self._create_flow_classifier( - self.fmt, { - 'l7_parameters': {'abc': 'def'} - }, - expected_res_status=400 - ) - - def test_create_flow_classifier_with_port_id(self): - self._test_create_flow_classifier({ - 'logical_source_port': None, - 'logical_destination_port': None, - }) - with self.port( - name='test1' - ) as port: - self._test_create_flow_classifier({ - 'logical_source_port': port['port']['id'], - 'logical_destination_port': port['port']['id'], - }) - - def test_create_flow_classifier_with_nouuid_port_id(self): - self._create_flow_classifier( - self.fmt, { - 'logical_source_port': 'abc' - }, - expected_res_status=400 - ) - self._create_flow_classifier( - self.fmt, { - 'logical_destination_port': 'abc' - }, - expected_res_status=400 - ) - - def test_create_flow_classifier_with_unknown_port_id(self): - self._create_flow_classifier( - self.fmt, { - 'logical_source_port': uuidutils.generate_uuid() - }, - expected_res_status=404 - ) - self._create_flow_classifier( - self.fmt, { - 'logical_destination_port': uuidutils.generate_uuid() - }, - expected_res_status=404 - ) - - def test_list_flow_classifiers(self): - with self.flow_classifier(flow_classifier={ - 'name': 'test1' - }) as fc1, self.flow_classifier(flow_classifier={ - 'name': 'test2', - }) as fc2: - fcs = [fc1, fc2] - self._test_list_resources( - 'flow_classifier', fcs - ) - - def test_list_flow_classifiers_with_params(self): - with self.flow_classifier(flow_classifier={ - 'name': 'test1' - }) as fc1, self.flow_classifier(flow_classifier={ - 'name': 'test2', - }) as fc2: - self._test_list_resources( - 'flow_classifier', [fc1], - query_params='name=test1' - ) - self._test_list_resources( - 'flow_classifier', [fc2], - query_params='name=test2' - ) - self._test_list_resources( - 'flow_classifier', [], - query_params='name=test3' - ) - - def test_list_flow_classifiers_with_unknown_params(self): - with self.flow_classifier(flow_classifier={ - 'name': 'test1' - }) as fc1, self.flow_classifier(flow_classifier={ - 'name': 'test2', - }) as fc2: - self._test_list_resources( - 'flow_classifier', [fc1, fc2], - query_params='hello=test3' - ) - - def test_show_flow_classifier(self): - with self.flow_classifier(flow_classifier={ - 'name': 'test1' - }) as fc: - req = self.new_show_request( - 'flow_classifiers', fc['flow_classifier']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - for k, v in six.iteritems(fc['flow_classifier']): - self.assertEqual(res['flow_classifier'][k], v) - - def test_show_flow_classifier_noexist(self): - req = self.new_show_request( - 'flow_classifiers', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_update_flow_classifier(self): - with self.flow_classifier(flow_classifier={ - 'name': 'test1', - 'description': 'desc1' - }) as fc: - updates = { - 'name': 'test2', - 'description': 'desc2', - } - req = self.new_update_request( - 'flow_classifiers', {'flow_classifier': updates}, - fc['flow_classifier']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - expected = fc['flow_classifier'] - expected.update(updates) - for k, v in six.iteritems(expected): - self.assertEqual(res['flow_classifier'][k], v) - req = self.new_show_request( - 'flow_classifiers', fc['flow_classifier']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - for k, v in six.iteritems(expected): - self.assertEqual(res['flow_classifier'][k], v) - - def _test_update_with_field( - self, fc, updates, expected_status_code - ): - req = self.new_update_request( - 'flow_classifiers', {'flow_classifier': updates}, - fc['flow_classifier']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, expected_status_code) - - def test_update_flow_classifer_unsupported_fields(self): - with self.flow_classifier(flow_classifier={ - 'name': 'test1', - 'description': 'desc1' - }) as fc: - self._test_update_with_field( - fc, {'ethertype': None}, 400) - self._test_update_with_field( - fc, {'protocol': None}, 400) - self._test_update_with_field( - fc, {'source_port_range_min': None}, 400) - self._test_update_with_field( - fc, {'source_port_range_max': None}, 400) - self._test_update_with_field( - fc, {'destination_port_range_min': None}, 400) - self._test_update_with_field( - fc, {'destination_port_range_max': None}, 400) - self._test_update_with_field( - fc, {'source_ip_prefix': None}, 400) - self._test_update_with_field( - fc, {'destination_ip_prefix': None}, 400) - self._test_update_with_field( - fc, {'l7_parameters': None}, 400) - - def test_delete_flow_classifier(self): - with self.flow_classifier(flow_classifier={ - 'name': 'test1' - }, do_delete=False) as fc: - req = self.new_delete_request( - 'flow_classifiers', fc['flow_classifier']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - req = self.new_show_request( - 'flow_classifiers', fc['flow_classifier']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_delete_flow_classifier_noexist(self): - req = self.new_delete_request( - 'flow_classifiers', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) diff --git a/networking_sfc/tests/unit/db/test_sfc_db.py b/networking_sfc/tests/unit/db/test_sfc_db.py deleted file mode 100644 index 70d57e3..0000000 --- a/networking_sfc/tests/unit/db/test_sfc_db.py +++ /dev/null @@ -1,1490 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import contextlib -import mock -import six -import webob.exc - -from oslo_config import cfg -from oslo_utils import importutils -from oslo_utils import uuidutils - -from neutron.api import extensions as api_ext -from neutron.common import config -import neutron.extensions as nextensions - -from networking_sfc.db import flowclassifier_db as fdb -from networking_sfc.db import sfc_db -from networking_sfc import extensions -from networking_sfc.extensions import flowclassifier as fc_ext -from networking_sfc.extensions import sfc -from networking_sfc.tests import base -from networking_sfc.tests.unit.db import test_flowclassifier_db - - -DB_SFC_PLUGIN_CLASS = ( - "networking_sfc.db.sfc_db.SfcDbPlugin" -) -extensions_path = ':'.join(extensions.__path__ + nextensions.__path__) - - -class SfcDbPluginTestCaseBase( - base.BaseTestCase -): - def _create_port_chain( - self, fmt, port_chain=None, expected_res_status=None, **kwargs - ): - ctx = kwargs.get('context', None) - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'port_chain': port_chain or {}} - if ctx is None: - data['port_chain'].update({'tenant_id': tenant_id}) - req = self.new_create_request( - 'port_chains', data, fmt, context=ctx - ) - res = req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(res.status_int, expected_res_status) - return res - - @contextlib.contextmanager - def port_chain(self, fmt=None, port_chain=None, do_delete=True, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_port_chain(fmt, port_chain, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - port_chain = self.deserialize(fmt or self.fmt, res) - yield port_chain - if do_delete: - self._delete('port_chains', port_chain['port_chain']['id']) - - def _create_port_pair_group( - self, fmt, port_pair_group=None, expected_res_status=None, **kwargs - ): - ctx = kwargs.get('context', None) - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'port_pair_group': port_pair_group or {}} - if ctx is None: - data['port_pair_group'].update({'tenant_id': tenant_id}) - req = self.new_create_request( - 'port_pair_groups', data, fmt, context=ctx - ) - res = req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(res.status_int, expected_res_status) - return res - - @contextlib.contextmanager - def port_pair_group( - self, fmt=None, port_pair_group=None, do_delete=True, **kwargs - ): - if not fmt: - fmt = self.fmt - res = self._create_port_pair_group(fmt, port_pair_group, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - port_pair_group = self.deserialize(fmt or self.fmt, res) - yield port_pair_group - if do_delete: - self._delete( - 'port_pair_groups', - port_pair_group['port_pair_group']['id']) - - def _create_port_pair( - self, fmt, port_pair=None, expected_res_status=None, **kwargs - ): - ctx = kwargs.get('context', None) - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'port_pair': port_pair or {}} - if ctx is None: - data['port_pair'].update({'tenant_id': tenant_id}) - req = self.new_create_request( - 'port_pairs', data, fmt, context=ctx - ) - res = req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(res.status_int, expected_res_status) - return res - - @contextlib.contextmanager - def port_pair(self, fmt=None, port_pair=None, do_delete=True, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_port_pair(fmt, port_pair, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - port_pair = self.deserialize(fmt or self.fmt, res) - yield port_pair - if do_delete: - self._delete('port_pairs', port_pair['port_pair']['id']) - - def _get_expected_port_pair(self, port_pair): - return { - 'name': port_pair.get('name') or '', - 'description': port_pair.get('description') or '', - 'egress': port_pair.get('egress'), - 'ingress': port_pair.get('ingress'), - 'service_function_parameters': port_pair.get( - 'service_function_parameters') or {'correlation': None} - } - - def _test_create_port_pair(self, port_pair, expected_port_pair=None): - if expected_port_pair is None: - expected_port_pair = self._get_expected_port_pair(port_pair) - with self.port_pair(port_pair=port_pair) as pp: - for k, v in six.iteritems(expected_port_pair): - self.assertEqual(pp['port_pair'][k], v) - - def _test_create_port_pairs( - self, port_pairs, expected_port_pairs=None - ): - if port_pairs: - port_pair = port_pairs.pop() - if expected_port_pairs: - expected_port_pair = expected_port_pairs.pop() - else: - expected_port_pair = self._get_expected_port_pair(port_pair) - with self.port_pair(port_pair=port_pair) as pp: - for k, v in six.iteritems(expected_port_pair): - self.assertEqual(pp['port_pair'][k], v) - - def _get_expected_port_pair_group(self, port_pair_group): - return { - 'name': port_pair_group.get('name') or '', - 'description': port_pair_group.get('description') or '', - 'port_pairs': port_pair_group.get('port_pairs') or [] - } - - def _test_create_port_pair_group( - self, port_pair_group, expected_port_pair_group=None - ): - if expected_port_pair_group is None: - expected_port_pair_group = self._get_expected_port_pair_group( - port_pair_group) - with self.port_pair_group(port_pair_group=port_pair_group) as pg: - for k, v in six.iteritems(expected_port_pair_group): - self.assertEqual(pg['port_pair_group'][k], v) - - def _test_create_port_pair_groups( - self, port_pair_groups, expected_port_pair_groups=None - ): - if port_pair_groups: - port_pair_group = port_pair_groups.pop() - if expected_port_pair_groups: - expected_port_pair_group = expected_port_pair_groups.pop() - else: - expected_port_pair_group = self._get_expected_port_pair_group( - port_pair_group) - with self.port_pair_group(port_pair_group=port_pair_group) as pg: - for k, v in six.iteritems(expected_port_pair_group): - self.assertEqual(pg['port_pair_group'][k], v) - - def _get_expected_port_chain(self, port_chain): - return { - 'name': port_chain.get('name') or '', - 'description': port_chain.get('description') or '', - 'port_pair_groups': port_chain['port_pair_groups'], - 'flow_classifiers': port_chain.get('flow_classifiers') or [], - 'chain_parameters': port_chain.get( - 'chain_parameters') or {'correlation': 'mpls'} - } - - def _test_create_port_chain(self, port_chain, expected_port_chain=None): - if expected_port_chain is None: - expected_port_chain = self._get_expected_port_chain(port_chain) - with self.port_chain(port_chain=port_chain) as pc: - for k, v in six.iteritems(expected_port_chain): - self.assertEqual(pc['port_chain'][k], v) - - def _test_create_port_chains( - self, port_chains, expected_port_chains=None - ): - if port_chains: - port_chain = port_chains.pop() - if expected_port_chains: - expected_port_chain = expected_port_chains.pop() - else: - expected_port_chain = self._get_expected_port_chain( - port_chain) - with self.port_chain(port_chain=port_chain) as pc: - for k, v in six.iteritems(expected_port_chain): - self.assertEqual(pc['port_chain'][k], v) - - -class SfcDbPluginTestCase( - base.NeutronDbPluginV2TestCase, - test_flowclassifier_db.FlowClassifierDbPluginTestCaseBase, - SfcDbPluginTestCaseBase -): - resource_prefix_map = dict([ - (k, sfc.SFC_PREFIX) - for k in sfc.RESOURCE_ATTRIBUTE_MAP.keys() - ] + [ - (k, fc_ext.FLOW_CLASSIFIER_PREFIX) - for k in fc_ext.RESOURCE_ATTRIBUTE_MAP.keys() - ]) - - def setUp(self, core_plugin=None, sfc_plugin=None, - flowclassifier_plugin=None, ext_mgr=None): - mock_log_p = mock.patch.object(sfc_db, 'LOG') - self.mock_log = mock_log_p.start() - cfg.CONF.register_opts(sfc.sfc_quota_opts, 'QUOTAS') - if not sfc_plugin: - sfc_plugin = DB_SFC_PLUGIN_CLASS - if not flowclassifier_plugin: - flowclassifier_plugin = ( - test_flowclassifier_db.DB_FLOWCLASSIFIER_PLUGIN_CLASS) - - service_plugins = { - sfc.SFC_EXT: sfc_plugin, - fc_ext.FLOW_CLASSIFIER_EXT: flowclassifier_plugin - } - sfc_db.SfcDbPlugin.supported_extension_aliases = [ - "sfc"] - sfc_db.SfcDbPlugin.path_prefix = sfc.SFC_PREFIX - fdb.FlowClassifierDbPlugin.supported_extension_aliases = [ - "flow_classifier"] - fdb.FlowClassifierDbPlugin.path_prefix = ( - fc_ext.FLOW_CLASSIFIER_PREFIX - ) - super(SfcDbPluginTestCase, self).setUp( - ext_mgr=ext_mgr, - plugin=core_plugin, - service_plugins=service_plugins - ) - if not ext_mgr: - self.sfc_plugin = importutils.import_object(sfc_plugin) - self.flowclassifier_plugin = importutils.import_object( - flowclassifier_plugin) - ext_mgr = api_ext.PluginAwareExtensionManager( - extensions_path, - { - sfc.SFC_EXT: self.sfc_plugin, - fc_ext.FLOW_CLASSIFIER_EXT: self.flowclassifier_plugin - } - ) - app = config.load_paste_app('extensions_test_app') - self.ext_api = api_ext.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - def test_create_port_chain(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'port_pair_groups': [pg['port_pair_group']['id']]}) - - def test_quota_create_port_chain(self): - cfg.CONF.set_override('quota_port_chain', 3, group='QUOTAS') - with self.port_pair_group( - port_pair_group={}, do_delete=False - ) as pg1, self.port_pair_group( - port_pair_group={}, do_delete=False - ) as pg2, self.port_pair_group( - port_pair_group={}, do_delete=False - ) as pg3, self.port_pair_group( - port_pair_group={}, do_delete=False - ) as pg4: - self._create_port_chain( - self.fmt, { - 'port_pair_groups': [pg1['port_pair_group']['id']] - }, expected_res_status=201) - self._create_port_chain( - self.fmt, { - 'port_pair_groups': [pg2['port_pair_group']['id']] - }, expected_res_status=201) - self._create_port_chain( - self.fmt, { - 'port_pair_groups': [pg3['port_pair_group']['id']] - }, expected_res_status=201) - self._create_port_chain( - self.fmt, { - 'port_pair_groups': [pg4['port_pair_group']['id']] - }, expected_res_status=409) - - def test_create_port_chain_all_fields(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'port_pair_groups': [pg['port_pair_group']['id']], - 'flow_classifiers': [], - 'name': 'abc', - 'description': 'def', - 'chain_parameters': {'correlation': 'mpls'} - }) - - def test_create_port_chain_multi_port_pair_groups(self): - with self.port_pair_group( - port_pair_group={} - ) as pg1, self.port_pair_group( - port_pair_group={} - ) as pg2: - self._test_create_port_chain({ - 'port_pair_groups': [ - pg1['port_pair_group']['id'], - pg2['port_pair_group']['id'] - ] - }) - - def test_create_port_chain_shared_port_pair_groups(self): - with self.port_pair_group( - port_pair_group={} - ) as pg1, self.port_pair_group( - port_pair_group={} - ) as pg2, self.port_pair_group( - port_pair_group={} - ) as pg3: - self._test_create_port_chains([{ - 'port_pair_groups': [ - pg1['port_pair_group']['id'], - pg2['port_pair_group']['id'] - ] - }, { - 'port_pair_groups': [ - pg1['port_pair_group']['id'], - pg3['port_pair_group']['id'] - ] - }]) - - def test_create_port_chain_shared_port_pair_groups_different_order(self): - with self.port_pair_group( - port_pair_group={} - ) as pg1, self.port_pair_group( - port_pair_group={} - ) as pg2: - self._test_create_port_chains([{ - 'port_pair_groups': [ - pg1['port_pair_group']['id'], - pg2['port_pair_group']['id'] - ] - }, { - 'port_pair_groups': [ - pg2['port_pair_group']['id'], - pg1['port_pair_group']['id'] - ] - }]) - - def test_create_port_chain_with_empty_chain_parameters(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'chain_parameters': {}, - 'port_pair_groups': [pg['port_pair_group']['id']] - }) - - def test_create_port_chain_with_none_chain_parameters(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'chain_parameters': None, - 'port_pair_groups': [pg['port_pair_group']['id']] - }) - - def test_create_port_chain_with_default_chain_parameters(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'chain_parameters': {'correlation': 'mpls'}, - 'port_pair_groups': [pg['port_pair_group']['id']] - }) - - def test_create_port_chain_with_none_flow_classifiers(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'flow_classifiers': None, - 'port_pair_groups': [pg['port_pair_group']['id']] - }) - - def test_create_port_chain_with_empty_flow_classifiers(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'flow_classifiers': [], - 'port_pair_groups': [pg['port_pair_group']['id']] - }) - - def test_create_port_chain_with_flow_classifiers(self): - with self.flow_classifier(flow_classifier={}) as fc: - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'flow_classifiers': [fc['flow_classifier']['id']], - 'port_pair_groups': [pg['port_pair_group']['id']] - }) - - def test_create_port_chain_with_multi_flow_classifiers(self): - with self.flow_classifier( - flow_classifier={} - ) as fc1, self.flow_classifier( - flow_classifier={} - ) as fc2: - with self.port_pair_group(port_pair_group={}) as pg: - self._test_create_port_chain({ - 'flow_classifiers': [ - fc1['flow_classifier']['id'], - fc2['flow_classifier']['id'] - ], - 'port_pair_groups': [pg['port_pair_group']['id']] - }) - - def test_create_port_chain_with_port_pairs(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pp1, self.port_pair(port_pair={ - 'ingress': dst_port['port']['id'], - 'egress': src_port['port']['id'] - }) as pp2: - with self.port_pair_group(port_pair_group={ - 'port_pairs': [ - pp1['port_pair']['id'] - ] - }) as pg1, self.port_pair_group(port_pair_group={ - 'port_pairs': [ - pp2['port_pair']['id'] - ] - }) as pg2: - self._test_create_port_chain({ - 'port_pair_groups': [ - pg1['port_pair_group']['id'], - pg2['port_pair_group']['id'] - ] - }) - - def test_create_port_chain_with_empty_port_pair_groups(self): - self._create_port_chain( - self.fmt, {'port_pair_groups': []}, - expected_res_status=400 - ) - - def test_create_port_chain_with_nonuuid_port_pair_group_id(self): - self._create_port_chain( - self.fmt, {'port_pair_groups': ['unknown']}, - expected_res_status=400 - ) - - def test_create_port_chain_with_unknown_port_pair_group_id(self): - self._create_port_chain( - self.fmt, {'port_pair_groups': [uuidutils.generate_uuid()]}, - expected_res_status=404 - ) - - def test_create_port_chain_with_same_port_pair_groups(self): - with self.port_pair_group( - port_pair_group={} - ) as pg: - with self.port_chain( - port_chain={ - 'port_pair_groups': [pg['port_pair_group']['id']] - } - ): - self._create_port_chain( - self.fmt, { - 'port_pair_groups': [pg['port_pair_group']['id']] - }, expected_res_status=409 - ) - - def test_create_port_chain_with_no_port_pair_groups(self): - self._create_port_chain( - self.fmt, {}, expected_res_status=400 - ) - - def test_create_port_chain_with_invalid_chain_parameters(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._create_port_chain( - self.fmt, { - 'chain_parameters': {'correlation': 'unknown'}, - 'port_pair_groups': [pg['port_pair_group']['id']] - }, expected_res_status=400 - ) - - def test_create_port_chain_unknown_flow_classifiers(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._create_port_chain( - self.fmt, { - 'flow_classifiers': [uuidutils.generate_uuid()], - 'port_pair_groups': [pg['port_pair_group']['id']] - }, expected_res_status=404 - ) - - def test_create_port_chain_nouuid_flow_classifiers(self): - with self.port_pair_group(port_pair_group={}) as pg: - self._create_port_chain( - self.fmt, { - 'flow_classifiers': ['unknown'], - 'port_pair_groups': [pg['port_pair_group']['id']] - }, expected_res_status=400 - ) - - def test_list_port_chains(self): - with self.port_pair_group( - port_pair_group={} - ) as pg1, self.port_pair_group( - port_pair_group={} - ) as pg2: - with self.port_chain(port_chain={ - 'port_pair_groups': [pg1['port_pair_group']['id']] - }) as pc1, self.port_chain(port_chain={ - 'port_pair_groups': [pg2['port_pair_group']['id']] - }) as pc2: - port_chains = [pc1, pc2] - self._test_list_resources( - 'port_chain', port_chains - ) - - def test_list_port_chains_with_params(self): - with self.port_pair_group( - port_pair_group={} - ) as pg1, self.port_pair_group( - port_pair_group={} - ) as pg2: - with self.port_chain(port_chain={ - 'name': 'test1', - 'port_pair_groups': [pg1['port_pair_group']['id']] - }) as pc1, self.port_chain(port_chain={ - 'name': 'test2', - 'port_pair_groups': [pg2['port_pair_group']['id']] - }) as pc2: - self._test_list_resources( - 'port_chain', [pc1], - query_params='name=test1' - ) - self._test_list_resources( - 'port_chain', [pc2], - query_params='name=test2' - ) - self._test_list_resources( - 'port_chain', [], - query_params='name=test3' - ) - - def test_list_port_chains_with_unknown_params(self): - with self.port_pair_group( - port_pair_group={} - ) as pg1, self.port_pair_group( - port_pair_group={} - ) as pg2: - with self.port_chain(port_chain={ - 'name': 'test1', - 'port_pair_groups': [pg1['port_pair_group']['id']] - }) as pc1, self.port_chain(port_chain={ - 'name': 'test2', - 'port_pair_groups': [pg2['port_pair_group']['id']] - }) as pc2: - self._test_list_resources( - 'port_chain', [pc1, pc2], - query_params='hello=test3' - ) - - def test_show_port_chain(self): - with self.port_pair_group( - port_pair_group={} - ) as pg: - with self.port_chain(port_chain={ - 'name': 'test1', - 'description': 'portchain', - 'port_pair_groups': [pg['port_pair_group']['id']] - }) as pc: - req = self.new_show_request( - 'port_chains', pc['port_chain']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - expected = self._get_expected_port_chain(pc['port_chain']) - for k, v in six.iteritems(expected): - self.assertEqual(res['port_chain'][k], v) - - def test_show_port_chain_noexist(self): - req = self.new_show_request( - 'port_chains', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_update_port_chain(self): - with self.flow_classifier( - flow_classifier={} - ) as fc1, self.flow_classifier( - flow_classifier={} - ) as fc2: - with self.port_pair_group( - port_pair_group={} - ) as pg: - with self.port_chain(port_chain={ - 'name': 'test1', - 'description': 'desc1', - 'port_pair_groups': [pg['port_pair_group']['id']], - 'flow_classifiers': [fc1['flow_classifier']['id']] - }) as pc: - updates = { - 'name': 'test2', - 'description': 'desc2', - 'flow_classifiers': [fc2['flow_classifier']['id']] - } - req = self.new_update_request( - 'port_chains', {'port_chain': updates}, - pc['port_chain']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - expected = pc['port_chain'] - expected.update(updates) - for k, v in six.iteritems(expected): - self.assertEqual(res['port_chain'][k], v) - req = self.new_show_request( - 'port_chains', pc['port_chain']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - for k, v in six.iteritems(expected): - self.assertEqual(res['port_chain'][k], v) - - def test_update_port_chain_port_pair_groups(self): - with self.port_pair_group( - port_pair_group={} - ) as pg1, self.port_pair_group( - port_pair_group={} - ) as pg2: - with self.port_chain(port_chain={ - 'port_pair_groups': [pg1['port_pair_group']['id']], - }) as pc: - updates = { - 'port_pair_groups': [pg2['port_pair_group']['id']] - } - req = self.new_update_request( - 'port_chains', {'port_chain': updates}, - pc['port_chain']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_port_chain_chain_parameters(self): - with self.port_pair_group( - port_pair_group={} - ) as pg: - with self.port_chain(port_chain={ - 'port_pair_groups': [pg['port_pair_group']['id']], - }) as pc: - updates = { - 'chain_parameters': {'correlation': 'mpls'} - } - req = self.new_update_request( - 'port_chains', {'port_chain': updates}, - pc['port_chain']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_delete_port_chain(self): - with self.port_pair_group( - port_pair_group={} - ) as pg: - with self.port_chain(port_chain={ - 'port_pair_groups': [pg['port_pair_group']['id']] - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_chains', pc['port_chain']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - req = self.new_show_request( - 'port_chains', pc['port_chain']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - req = self.new_show_request( - 'port_pair_groups', pg['port_pair_group']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 200) - - def test_delete_port_chain_noexist(self): - req = self.new_delete_request( - 'port_chains', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_delete_flow_classifier_port_chain_exist(self): - with self.flow_classifier(flow_classifier={ - }) as fc: - with self.port_pair_group(port_pair_group={ - }) as pg: - with self.port_chain(port_chain={ - 'port_pair_groups': [pg['port_pair_group']['id']], - 'flow_classifiers': [fc['flow_classifier']['id']] - }): - req = self.new_delete_request( - 'flow_classifiers', fc['flow_classifier']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 409) - - def test_create_port_pair_group(self): - self._test_create_port_pair_group({}) - - def test_quota_create_port_pair_group_quota(self): - cfg.CONF.set_override('quota_port_pair_group', 3, group='QUOTAS') - self._create_port_pair_group( - self.fmt, {'port_pairs': []}, expected_res_status=201 - ) - self._create_port_pair_group( - self.fmt, {'port_pairs': []}, expected_res_status=201 - ) - self._create_port_pair_group( - self.fmt, {'port_pairs': []}, expected_res_status=201 - ) - self._create_port_pair_group( - self.fmt, {'port_pairs': []}, expected_res_status=409 - ) - - def test_create_port_pair_group_all_fields(self): - self._test_create_port_pair_group({ - 'name': 'test1', - 'description': 'desc1', - 'port_pairs': [] - }) - - def test_create_port_pair_group_with_port_pairs(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pp1, self.port_pair(port_pair={ - 'ingress': dst_port['port']['id'], - 'egress': src_port['port']['id'] - }) as pp2: - self._test_create_port_pair_group({ - 'port_pairs': [ - pp1['port_pair']['id'], - pp2['port_pair']['id'] - ] - }) - - def test_create_port_pair_group_with_nouuid_port_pair_id(self): - self._create_port_pair_group( - self.fmt, {'port_pairs': ['unknown']}, - expected_res_status=400 - ) - - def test_create_port_pair_group_with_unknown_port_pair_id(self): - self._create_port_pair_group( - self.fmt, {'port_pairs': [uuidutils.generate_uuid()]}, - expected_res_status=404 - ) - - def test_create_port_pair_group_share_port_pair_id(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pp: - with self.port_pair_group(port_pair_group={ - 'port_pairs': [pp['port_pair']['id']] - }): - self._create_port_pair_group( - self.fmt, {'port_pairs': [pp['port_pair']['id']]}, - expected_res_status=409 - ) - - def test_list_port_pair_groups(self): - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }) as pc1, self.port_pair_group(port_pair_group={ - 'name': 'test2' - }) as pc2: - port_pair_groups = [pc1, pc2] - self._test_list_resources( - 'port_pair_group', port_pair_groups - ) - - def test_list_port_pair_groups_with_params(self): - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }) as pc1, self.port_pair_group(port_pair_group={ - 'name': 'test2' - }) as pc2: - self._test_list_resources( - 'port_pair_group', [pc1], - query_params='name=test1' - ) - self._test_list_resources( - 'port_pair_group', [pc2], - query_params='name=test2' - ) - self._test_list_resources( - 'port_pair_group', [], - query_params='name=test3' - ) - - def test_list_port_pair_groups_with_unknown_params(self): - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }) as pc1, self.port_pair_group(port_pair_group={ - 'name': 'test2' - }) as pc2: - self._test_list_resources( - 'port_pair_group', [pc1, pc2], - query_params='hello=test3' - ) - - def test_show_port_pair_group(self): - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }) as pc: - req = self.new_show_request( - 'port_pair_groups', pc['port_pair_group']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - for k, v in six.iteritems(pc['port_pair_group']): - self.assertEqual(res['port_pair_group'][k], v) - - def test_show_port_pair_group_noexist(self): - req = self.new_show_request( - 'port_pair_groups', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_update_port_pair_group(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pp1, self.port_pair(port_pair={ - 'ingress': dst_port['port']['id'], - 'egress': src_port['port']['id'] - }) as pp2: - with self.port_pair_group(port_pair_group={ - 'name': 'test1', - 'description': 'desc1', - 'port_pairs': [pp1['port_pair']['id']] - }) as pg: - updates = { - 'name': 'test2', - 'description': 'desc2', - 'port_pairs': [pp2['port_pair']['id']] - } - req = self.new_update_request( - 'port_pair_groups', {'port_pair_group': updates}, - pg['port_pair_group']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - expected = pg['port_pair_group'] - expected.update(updates) - for k, v in six.iteritems(expected): - self.assertEqual(res['port_pair_group'][k], v) - req = self.new_show_request( - 'port_pair_groups', pg['port_pair_group']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - for k, v in six.iteritems(expected): - self.assertEqual(res['port_pair_group'][k], v) - - def test_delete_port_pair_group(self): - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_pair_groups', pc['port_pair_group']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - req = self.new_show_request( - 'port_pair_groups', pc['port_pair_group']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_delete_port_pair_group_port_chain_exist(self): - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }) as pg: - with self.port_chain(port_chain={ - 'port_pair_groups': [pg['port_pair_group']['id']] - }): - req = self.new_delete_request( - 'port_pair_groups', pg['port_pair_group']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 409) - - def test_delete_port_pair_group_noexist(self): - req = self.new_delete_request( - 'port_pair_groups', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_create_port_pair(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - self._test_create_port_pair({ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) - - def test_quota_create_port_pair_quota(self): - cfg.CONF.set_override('quota_port_pair', 3, group='QUOTAS') - with self.port( - name='port1', - device_id='default' - ) as src_port1, self.port( - name='port2', - device_id='default' - ) as dst_port1, self.port( - name='port3', - device_id='default' - ) as src_port2, self.port( - name='port4', - device_id='default' - ) as dst_port2, self.port( - name='port5', - device_id='default' - ) as src_port3, self.port( - name='port6', - device_id='default' - ) as dst_port3, self.port( - name='port7', - device_id='default' - ) as src_port4, self.port( - name='port8', - device_id='default' - ) as dst_port4: - self._create_port_pair( - self.fmt, { - 'ingress': src_port1['port']['id'], - 'egress': dst_port1['port']['id'] - }, expected_res_status=201) - self._create_port_pair( - self.fmt, { - 'ingress': src_port2['port']['id'], - 'egress': dst_port2['port']['id'] - }, expected_res_status=201) - self._create_port_pair( - self.fmt, { - 'ingress': src_port3['port']['id'], - 'egress': dst_port3['port']['id'] - }, expected_res_status=201) - self._create_port_pair( - self.fmt, { - 'ingress': src_port4['port']['id'], - 'egress': dst_port4['port']['id'] - }, expected_res_status=409) - - def test_create_port_pair_all_fields(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - self._test_create_port_pair({ - 'name': 'test1', - 'description': 'desc1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'], - 'service_function_parameters': {'correlation': None} - }) - - def test_create_port_pair_none_service_function_parameters(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - self._test_create_port_pair({ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'], - 'service_function_parameters': None - }) - - def test_create_port_pair_empty_service_function_parameters(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - self._test_create_port_pair({ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'], - 'service_function_parameters': {} - }) - - def test_create_port_pair_with_src_dst_same_port(self): - with self.port( - name='port1', - device_id='default' - ) as src_dst_port: - self._test_create_port_pair({ - 'ingress': src_dst_port['port']['id'], - 'egress': src_dst_port['port']['id'] - }) - - def test_create_port_pair_empty_input(self): - self._create_port_pair(self.fmt, {}, expected_res_status=400) - - def test_create_port_pair_with_no_ingress(self): - with self.port( - name='port1', - device_id='default' - ) as dst_port: - self._create_port_pair( - self.fmt, - { - 'egress': dst_port['port']['id'] - }, - expected_res_status=400 - ) - - def test_create_port_pair_with_no_egress(self): - with self.port( - name='port1', - device_id='default' - ) as src_port: - self._create_port_pair( - self.fmt, - { - 'ingress': src_port['port']['id'] - }, - expected_res_status=400 - ) - - def test_create_port_pair_with_nouuid_ingress(self): - with self.port( - name='port1', - device_id='default' - ) as dst_port: - self._create_port_pair( - self.fmt, - { - 'ingress': '1', - 'egress': dst_port['port']['id'] - }, - expected_res_status=400 - ) - - def test_create_port_pair_with_unknown_ingress(self): - with self.port( - name='port1', - device_id='default' - ) as dst_port: - self._create_port_pair( - self.fmt, - { - 'ingress': uuidutils.generate_uuid(), - 'egress': dst_port['port']['id'] - }, - expected_res_status=404 - ) - - def test_create_port_pair_with_nouuid_egress(self): - with self.port( - name='port1', - device_id='default' - ) as src_port: - self._create_port_pair( - self.fmt, - { - 'ingress': src_port['port']['id'], - 'egress': '1' - }, - expected_res_status=400 - ) - - def test_create_port_pair_with_unkown_egress(self): - with self.port( - name='port1', - device_id='default' - ) as src_port: - self._create_port_pair( - self.fmt, - { - 'ingress': src_port['port']['id'], - 'egress': uuidutils.generate_uuid() - }, - expected_res_status=404 - ) - - def test_create_port_pair_ingress_egress_different_hosts(self): - with self.port( - name='port1', - device_id='device1' - ) as src_port, self.port( - name='port2', - device_id='device2' - ) as dst_port: - self._create_port_pair( - self.fmt, - { - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }, - expected_res_status=400 - ) - - def test_create_port_pair_with_invalid_service_function_parameters(self): - with self.port( - name='port1', - device_id='default' - ) as src_dst_port: - self._create_port_pair( - self.fmt, - { - 'ingress': src_dst_port['port']['id'], - 'egress': src_dst_port['port']['id'], - 'service_function_parameters': {'abc': 'def'} - }, - expected_res_status=400 - ) - - def test_list_port_pairs(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc1, self.port_pair(port_pair={ - 'ingress': dst_port['port']['id'], - 'egress': src_port['port']['id'] - }) as pc2: - port_pairs = [pc1, pc2] - self._test_list_resources( - 'port_pair', port_pairs - ) - - def test_list_port_pairs_with_params(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc1, self.port_pair(port_pair={ - 'name': 'test2', - 'ingress': dst_port['port']['id'], - 'egress': src_port['port']['id'] - }) as pc2: - self._test_list_resources( - 'port_pair', [pc1], - query_params='name=test1' - ) - self._test_list_resources( - 'port_pair', [pc2], - query_params='name=test2' - ) - self._test_list_resources( - 'port_pair', [], - query_params='name=test3' - ) - - def test_list_port_pairs_with_unknown_params(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc1, self.port_pair(port_pair={ - 'name': 'test2', - 'ingress': dst_port['port']['id'], - 'egress': src_port['port']['id'] - }) as pc2: - port_pairs = [pc1, pc2] - self._test_list_resources( - 'port_pair', port_pairs, - query_params='hello=test3' - ) - - def test_show_port_pair(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - req = self.new_show_request( - 'port_pairs', pc['port_pair']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - for k, v in six.iteritems(pc['port_pair']): - self.assertEqual(res['port_pair'][k], v) - - def test_show_port_pair_noexist(self): - req = self.new_show_request( - 'port_pairs', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_update_port_pair(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'description': 'desc1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - updates = { - 'name': 'test2', - 'description': 'desc2' - } - req = self.new_update_request( - 'port_pairs', {'port_pair': updates}, - pc['port_pair']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - expected = pc['port_pair'] - expected.update(updates) - for k, v in six.iteritems(expected): - self.assertEqual(res['port_pair'][k], v) - req = self.new_show_request( - 'port_pairs', pc['port_pair']['id'] - ) - res = self.deserialize( - self.fmt, req.get_response(self.ext_api) - ) - for k, v in six.iteritems(expected): - self.assertEqual(res['port_pair'][k], v) - - def test_update_port_pair_service_function_parameters(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'description': 'desc1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - updates = { - 'service_function_parameters': { - 'correlation': None - } - } - req = self.new_update_request( - 'port_pairs', {'port_pair': updates}, - pc['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_port_pair_ingress(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'description': 'desc1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - updates = { - 'ingress': dst_port['port']['id'] - } - req = self.new_update_request( - 'port_pairs', {'port_pair': updates}, - pc['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_update_port_pair_egress(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'description': 'desc1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - updates = { - 'egress': src_port['port']['id'] - } - req = self.new_update_request( - 'port_pairs', {'port_pair': updates}, - pc['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 400) - - def test_delete_port_pair(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_pairs', pc['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - req = self.new_show_request( - 'port_pairs', pc['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_delete_port_pair_noexist(self): - req = self.new_delete_request( - 'port_pairs', '1' - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 404) - - def test_delete_port_pair_port_pair_group_exist(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pp: - with self.port_pair_group(port_pair_group={ - 'port_pairs': [pp['port_pair']['id']] - }): - req = self.new_delete_request( - 'port_pairs', pp['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 409) - - def test_delete_ingress_port_pair_exist(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }): - req = self.new_delete_request( - 'ports', src_port['port']['id'] - ) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 500) - - def test_delete_egress_port_pair_exist(self): - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }): - req = self.new_delete_request( - 'ports', dst_port['port']['id'] - ) - res = req.get_response(self.api) - self.assertEqual(res.status_int, 500) diff --git a/networking_sfc/tests/unit/extensions/__init__.py b/networking_sfc/tests/unit/extensions/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/extensions/test_flowclassifier.py b/networking_sfc/tests/unit/extensions/test_flowclassifier.py deleted file mode 100644 index 7026ac5..0000000 --- a/networking_sfc/tests/unit/extensions/test_flowclassifier.py +++ /dev/null @@ -1,603 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import mock -from webob import exc -import webtest - -from oslo_utils import uuidutils - -from neutron.api.v2 import resource as api_res_log -from neutron.common import config -from neutron import manager -from neutron.notifiers import nova as nova_log - -from neutron.tests.unit.api.v2 import test_base as test_api_v2 -from neutron.tests.unit.extensions import base as test_api_v2_extension - -from networking_sfc.extensions import flowclassifier as fc_ext - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - -FLOW_CLASSIFIER_PATH = (fc_ext.FLOW_CLASSIFIER_PREFIX[1:] + '/' + - fc_ext.FLOW_CLASSIFIER_EXT + 's') - - -class FlowClassifierExtensionTestCase( - test_api_v2_extension.ExtensionTestCase -): - fmt = 'json' - - def setUp(self): - self._mock_unncessary_logging() - super(FlowClassifierExtensionTestCase, self).setUp() - self._setUpExtension( - 'networking_sfc.extensions.flowclassifier.' - 'FlowClassifierPluginBase', - fc_ext.FLOW_CLASSIFIER_EXT, - fc_ext.RESOURCE_ATTRIBUTE_MAP, - fc_ext.Flowclassifier, - fc_ext.FLOW_CLASSIFIER_PREFIX[1:], - plural_mappings={} - ) - - def _mock_unncessary_logging(self): - mock_log_cfg_p = mock.patch.object(config, 'LOG') - self.mock_log_cfg = mock_log_cfg_p.start() - - mock_log_manager_p = mock.patch.object(manager, 'LOG') - self.mock_log_manager = mock_log_manager_p.start() - - mock_log_nova_p = mock.patch.object(nova_log, 'LOG') - self.mock_log_nova = mock_log_nova_p.start() - - mock_log_api_res_log_p = mock.patch.object(api_res_log, 'LOG') - self.mock_log_api_res_log = mock_log_api_res_log_p.start() - - def _get_expected_flow_classifier(self, data): - source_port_range_min = data['flow_classifier'].get( - 'source_port_range_min') - if source_port_range_min is not None: - source_port_range_min = int(source_port_range_min) - source_port_range_max = data['flow_classifier'].get( - 'source_port_range_max') - if source_port_range_max is not None: - source_port_range_max = int(source_port_range_max) - destination_port_range_min = data['flow_classifier'].get( - 'destination_port_range_min') - if destination_port_range_min is not None: - destination_port_range_min = int(destination_port_range_min) - destination_port_range_max = data['flow_classifier'].get( - 'destination_port_range_max') - if destination_port_range_max is not None: - destination_port_range_max = int(destination_port_range_max) - - return {'flow_classifier': { - 'name': data['flow_classifier'].get('name') or '', - 'description': data['flow_classifier'].get('description') or '', - 'tenant_id': data['flow_classifier']['tenant_id'], - 'source_port_range_min': source_port_range_min, - 'source_port_range_max': source_port_range_max, - 'destination_port_range_min': destination_port_range_min, - 'destination_port_range_max': destination_port_range_max, - 'l7_parameters': data['flow_classifier'].get( - 'l7_parameters') or {}, - 'destination_ip_prefix': data['flow_classifier'].get( - 'destination_ip_prefix'), - 'source_ip_prefix': data['flow_classifier'].get( - 'source_ip_prefix'), - 'logical_source_port': data['flow_classifier'].get( - 'logical_source_port'), - 'logical_destination_port': data['flow_classifier'].get( - 'logical_destination_port'), - 'ethertype': data['flow_classifier'].get( - 'ethertype') or 'IPv4', - 'protocol': data['flow_classifier'].get( - 'protocol') - }} - - def _clean_expected_flow_classifier(self, expected_flow_classifier): - if 'logical_source_port' in expected_flow_classifier: - del expected_flow_classifier['logical_source_port'] - if 'logical_destination_port' in expected_flow_classifier: - del expected_flow_classifier['logical_destination_port'] - - def test_create_flow_classifier(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'tenant_id': _uuid(), - }} - expected_data = self._get_expected_flow_classifier(data) - return_value = copy.copy(expected_data['flow_classifier']) - return_value.update({'id': flowclassifier_id}) - self._clean_expected_flow_classifier(return_value) - instance = self.plugin.return_value - instance.create_flow_classifier.return_value = return_value - res = self.api.post( - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_flow_classifier.assert_called_with( - mock.ANY, - flow_classifier=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(return_value, res['flow_classifier']) - - def test_create_flow_classifier_port_string(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'source_port_range_min': '100', - 'source_port_range_max': '200', - 'destination_port_range_min': '100', - 'destination_port_range_max': '200', - 'tenant_id': _uuid(), - }} - expected_data = self._get_expected_flow_classifier(data) - return_value = copy.copy(expected_data['flow_classifier']) - return_value.update({'id': flowclassifier_id}) - self._clean_expected_flow_classifier(return_value) - instance = self.plugin.return_value - instance.create_flow_classifier.return_value = return_value - res = self.api.post( - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_flow_classifier.assert_called_with( - mock.ANY, - flow_classifier=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(return_value, res['flow_classifier']) - - def test_create_flow_classifier_ip_prefix_with_mask(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'source_ip_prefix': '10.0.0.0/8', - 'tenant_id': _uuid(), - }} - expected_data = self._get_expected_flow_classifier(data) - return_value = copy.copy(expected_data['flow_classifier']) - return_value.update({'id': flowclassifier_id}) - self._clean_expected_flow_classifier(return_value) - instance = self.plugin.return_value - instance.create_flow_classifier.return_value = return_value - res = self.api.post( - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_flow_classifier.assert_called_with( - mock.ANY, - flow_classifier=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(return_value, res['flow_classifier']) - - def test_create_flow_classifier_non_l7_parameters(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'tenant_id': _uuid(), - 'l7_parameters': None - }} - expected_data = self._get_expected_flow_classifier(data) - return_value = copy.copy(expected_data['flow_classifier']) - return_value.update({'id': flowclassifier_id}) - self._clean_expected_flow_classifier(return_value) - instance = self.plugin.return_value - instance.create_flow_classifier.return_value = return_value - res = self.api.post( - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_flow_classifier.assert_called_with( - mock.ANY, - flow_classifier=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(return_value, res['flow_classifier']) - - def test_create_flow_classifier_default_ethertype(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'tenant_id': _uuid(), - 'ethertype': 'IPv4' - }} - expected_data = self._get_expected_flow_classifier(data) - return_value = copy.copy(expected_data['flow_classifier']) - return_value.update({'id': flowclassifier_id}) - self._clean_expected_flow_classifier(return_value) - instance = self.plugin.return_value - instance.create_flow_classifier.return_value = return_value - res = self.api.post( - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_flow_classifier.assert_called_with( - mock.ANY, - flow_classifier=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(return_value, res['flow_classifier']) - - def test_create_flow_classifier_all_fields(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'name': 'test1', - 'description': 'desc', - 'tenant_id': _uuid(), - 'source_port_range_min': 100, - 'source_port_range_max': 200, - 'destination_port_range_min': 100, - 'destination_port_range_max': 200, - 'l7_parameters': {}, - 'destination_ip_prefix': '10.0.0.0/8', - 'source_ip_prefix': '10.0.0.0/8', - 'logical_source_port': _uuid(), - 'logical_destination_port': _uuid(), - 'ethertype': None, - 'protocol': None - }} - expected_data = self._get_expected_flow_classifier(data) - return_value = copy.copy(expected_data['flow_classifier']) - return_value.update({'id': flowclassifier_id}) - self._clean_expected_flow_classifier(return_value) - instance = self.plugin.return_value - instance.create_flow_classifier.return_value = return_value - res = self.api.post( - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_flow_classifier.assert_called_with( - mock.ANY, - flow_classifier=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(return_value, res['flow_classifier']) - - def test_create_flow_classifier_invalid_l7_parameters(self): - data = {'flow_classifier': { - 'l7_parameters': {'abc': 'def'}, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_flow_classifier_invalid_protocol(self): - data = {'flow_classifier': { - 'protocol': 'unknown', - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_flow_classifier_invalid_ethertype(self): - data = {'flow_classifier': { - 'ethertype': 'unknown', - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_flow_classifier_port_small(self): - data = {'flow_classifier': { - 'source_port_range_min': -1, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_flow_classifier_port_large(self): - data = {'flow_classifier': { - 'source_port_range_min': 65536, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_flow_classifier_ip_prefix_no_cidr(self): - data = {'flow_classifier': { - 'source_ip_prefix': '10.0.0.0', - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_flow_classifier_ip_prefix_invalid_cidr(self): - data = {'flow_classifier': { - 'source_ip_prefix': '10.0.0.0/33', - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_flow_classifier_port_id_nouuid(self): - data = {'flow_classifier': { - 'logical_source_port': 'unknown', - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_list(self): - flowclassifier_id = _uuid() - return_value = [{ - 'tenant_id': _uuid(), - 'id': flowclassifier_id - }] - instance = self.plugin.return_value - instance.get_flow_classifiers.return_value = return_value - - res = self.api.get( - _get_path(FLOW_CLASSIFIER_PATH, fmt=self.fmt)) - - instance.get_flow_classifiers.assert_called_with( - mock.ANY, - fields=mock.ANY, - filters=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('flow_classifiers', res) - self.assertEqual(res['flow_classifiers'], return_value) - - def test_flow_classifier_get(self): - flowclassifier_id = _uuid() - return_value = { - 'tenant_id': _uuid(), - 'id': flowclassifier_id - } - - instance = self.plugin.return_value - instance.get_flow_classifier.return_value = return_value - - res = self.api.get( - _get_path( - FLOW_CLASSIFIER_PATH, - id=flowclassifier_id, fmt=self.fmt - ) - ) - - instance.get_flow_classifier.assert_called_with( - mock.ANY, - flowclassifier_id, - fields=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(return_value, res['flow_classifier']) - - def test_flow_classifier_update(self): - flowclassifier_id = _uuid() - update_data = {'flow_classifier': { - 'name': 'new_name', - 'description': 'new_desc', - }} - return_value = { - 'tenant_id': _uuid(), - 'id': flowclassifier_id - } - - instance = self.plugin.return_value - instance.update_flow_classifier.return_value = return_value - - res = self.api.put( - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_flow_classifier.assert_called_with( - mock.ANY, flowclassifier_id, - flow_classifier=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('flow_classifier', res) - self.assertEqual(res['flow_classifier'], return_value) - - def test_flow_classifier_update_source_port_range_min(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'source_port_range_min': 100, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_source_port_range_max(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'source_port_range_max': 100, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_destination_port_range_min(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'destination_port_range_min': 100, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_destination_port_range_max(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'destination_port_range_max': 100, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_source_ip_prefix(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'source_ip_prefix': '10.0.0.0/8', - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_destination_ip_prefix(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'destination_ip_prefix': '10.0.0.0/8', - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_logical_source_port(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'logical_source_port': _uuid(), - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_logical_destination_port(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'logical_destination_port': _uuid(), - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_ethertype(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'ethertype': None, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_protocol(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'protococol': None, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_update_l7_parameters(self): - flowclassifier_id = _uuid() - data = {'flow_classifier': { - 'l7_parameters': {}, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(FLOW_CLASSIFIER_PATH, id=flowclassifier_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_flow_classifier_delete(self): - self._test_entity_delete('flow_classifier') diff --git a/networking_sfc/tests/unit/extensions/test_sfc.py b/networking_sfc/tests/unit/extensions/test_sfc.py deleted file mode 100644 index 01b7d8c..0000000 --- a/networking_sfc/tests/unit/extensions/test_sfc.py +++ /dev/null @@ -1,751 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import mock -from webob import exc -import webtest - -from oslo_utils import uuidutils - -from neutron.api.v2 import resource as api_res_log -from neutron.common import config as cfg -from neutron import manager -from neutron.notifiers import nova as nova_log - -from neutron.tests.unit.api.v2 import test_base as test_api_v2 -from neutron.tests.unit.extensions import base as test_api_v2_extension - -from networking_sfc.extensions import sfc as sfc_ext - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - -PORT_CHAIN_PATH = (sfc_ext.SFC_PREFIX[1:] + '/port_chains') -PORT_PAIR_PATH = (sfc_ext.SFC_PREFIX[1:] + '/port_pairs') -PORT_PAIR_GROUP_PATH = (sfc_ext.SFC_PREFIX[1:] + '/port_pair_groups') - - -class SfcExtensionTestCase(test_api_v2_extension.ExtensionTestCase): - fmt = 'json' - - def setUp(self): - self._mock_unncessary_looging() - super(SfcExtensionTestCase, self).setUp() - self._setUpExtension( - 'networking_sfc.extensions.sfc.SfcPluginBase', - sfc_ext.SFC_EXT, - sfc_ext.RESOURCE_ATTRIBUTE_MAP, - sfc_ext.Sfc, - sfc_ext.SFC_PREFIX[1:], - plural_mappings={} - ) - - def _mock_unncessary_looging(self): - mock_log_cfg_p = mock.patch.object(cfg, 'LOG') - self.mock_log_cfg = mock_log_cfg_p.start() - - mock_log_manager_p = mock.patch.object(manager, 'LOG') - self.mock_log_manager = mock_log_manager_p.start() - - mock_log_nova_p = mock.patch.object(nova_log, 'LOG') - self.mock_log_nova = mock_log_nova_p.start() - - mock_log_api_res_log_p = mock.patch.object(api_res_log, 'LOG') - self.mock_log_api_res_log = mock_log_api_res_log_p.start() - - def _get_expected_port_chain(self, data): - return {'port_chain': { - 'description': data['port_chain'].get('description') or '', - 'name': data['port_chain'].get('name') or '', - 'port_pair_groups': data['port_chain']['port_pair_groups'], - 'chain_parameters': data['port_chain'].get( - 'chain_parameters') or {'correlation': 'mpls'}, - 'flow_classifiers': data['port_chain'].get( - 'flow_classifiers') or [], - 'tenant_id': data['port_chain']['tenant_id'] - }} - - def test_create_port_chain(self): - portchain_id = _uuid() - data = {'port_chain': { - 'port_pair_groups': [_uuid()], - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_chain(data) - return_value = copy.copy(expected_data['port_chain']) - return_value.update({'id': portchain_id}) - instance = self.plugin.return_value - instance.create_port_chain.return_value = return_value - res = self.api.post(_get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_chain.assert_called_with( - mock.ANY, - port_chain=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_chain', res) - self.assertEqual(return_value, res['port_chain']) - - def test_create_port_chain_all_fields(self): - portchain_id = _uuid() - data = {'port_chain': { - 'description': 'desc', - 'name': 'test1', - 'port_pair_groups': [_uuid()], - 'chain_parameters': {'correlation': 'mpls'}, - 'flow_classifiers': [], - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_chain(data) - return_value = copy.copy(expected_data['port_chain']) - return_value.update({'id': portchain_id}) - instance = self.plugin.return_value - instance.create_port_chain.return_value = return_value - res = self.api.post(_get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_chain.assert_called_with( - mock.ANY, - port_chain=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_chain', res) - self.assertEqual(return_value, res['port_chain']) - - def test_create_port_chain_none_chain_parameters(self): - portchain_id = _uuid() - data = {'port_chain': { - 'port_pair_groups': [_uuid()], - 'chain_parameters': None, - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_chain(data) - return_value = copy.copy(expected_data['port_chain']) - return_value.update({'id': portchain_id}) - instance = self.plugin.return_value - instance.create_port_chain.return_value = return_value - res = self.api.post(_get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_chain.assert_called_with( - mock.ANY, - port_chain=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_chain', res) - self.assertEqual(return_value, res['port_chain']) - - def test_create_port_chain_empty_chain_parameters(self): - portchain_id = _uuid() - data = {'port_chain': { - 'port_pair_groups': [_uuid()], - 'chain_parameters': {}, - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_chain(data) - return_value = copy.copy(expected_data['port_chain']) - return_value.update({'id': portchain_id}) - instance = self.plugin.return_value - instance.create_port_chain.return_value = return_value - res = self.api.post(_get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_chain.assert_called_with( - mock.ANY, - port_chain=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_chain', res) - self.assertEqual(return_value, res['port_chain']) - - def test_create_port_chain_empty_port_pair_groups(self): - data = {'port_chain': { - 'port_pair_groups': [], - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_port_chain_nonuuid_port_pair_groups(self): - data = {'port_chain': { - 'port_pair_groups': ['nouuid'], - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_port_chain_nonuuid_flow_classifiers(self): - data = {'port_chain': { - 'port_pair_groups': [_uuid()], - 'flow_classifiers': ['nouuid'], - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_port_chain_invalid_chain_parameters(self): - data = {'port_chain': { - 'port_pair_groups': [_uuid()], - 'chain_parameters': {'abc': 'def'}, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_CHAIN_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_chain_list(self): - portchain_id = _uuid() - return_value = [{ - 'tenant_id': _uuid(), - 'id': portchain_id - }] - instance = self.plugin.return_value - instance.get_port_chains.return_value = return_value - - res = self.api.get(_get_path(PORT_CHAIN_PATH, fmt=self.fmt)) - - instance.get_port_chains.assert_called_with( - mock.ANY, - fields=mock.ANY, - filters=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_chains', res) - self.assertEqual(res['port_chains'], return_value) - - def test_port_chain_get(self): - portchain_id = _uuid() - return_value = { - 'tenant_id': _uuid(), - 'id': portchain_id - } - - instance = self.plugin.return_value - instance.get_port_chain.return_value = return_value - - res = self.api.get(_get_path(PORT_CHAIN_PATH, - id=portchain_id, fmt=self.fmt)) - - instance.get_port_chain.assert_called_with( - mock.ANY, - portchain_id, - fields=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_chain', res) - self.assertEqual(return_value, res['port_chain']) - - def test_port_chain_update(self): - portchain_id = _uuid() - update_data = {'port_chain': { - 'name': 'new_name', - 'description': 'new_desc', - 'flow_classifiers': [_uuid()] - }} - return_value = { - 'tenant_id': _uuid(), - 'id': portchain_id - } - - instance = self.plugin.return_value - instance.update_port_chain.return_value = return_value - - res = self.api.put(_get_path(PORT_CHAIN_PATH, id=portchain_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_port_chain.assert_called_with( - mock.ANY, portchain_id, - port_chain=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_chain', res) - self.assertEqual(res['port_chain'], return_value) - - def test_port_chain_update_nonuuid_flow_classifiers(self): - portchain_id = _uuid() - data = {'port_chain': { - 'flow_classifiers': ['nouuid'], - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(PORT_CHAIN_PATH, id=portchain_id, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_chain_update_port_pair_groups(self): - portchain_id = _uuid() - update_data = {'port_chain': { - 'port_pair_groups': [_uuid()] - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(PORT_CHAIN_PATH, id=portchain_id, - fmt=self.fmt), - self.serialize(update_data) - ) - - def test_port_chain_update_chain_parameters(self): - portchain_id = _uuid() - update_data = {'port_chain': { - 'chain_parameters': {} - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(PORT_CHAIN_PATH, id=portchain_id, - fmt=self.fmt), - self.serialize(update_data) - ) - - def test_port_chain_delete(self): - self._test_entity_delete('port_chain') - - def _get_expected_port_pair_group(self, data): - return {'port_pair_group': { - 'description': data['port_pair_group'].get('description') or '', - 'name': data['port_pair_group'].get('name') or '', - 'port_pairs': data['port_pair_group'].get('port_pairs') or [], - 'tenant_id': data['port_pair_group']['tenant_id'] - }} - - def test_create_port_pair_group(self): - portpairgroup_id = _uuid() - data = {'port_pair_group': { - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_pair_group(data) - return_value = copy.copy(expected_data['port_pair_group']) - return_value.update({'id': portpairgroup_id}) - instance = self.plugin.return_value - instance.create_port_pair_group.return_value = return_value - res = self.api.post( - _get_path(PORT_PAIR_GROUP_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_pair_group.assert_called_with( - mock.ANY, - port_pair_group=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_pair_group', res) - self.assertEqual(return_value, res['port_pair_group']) - - def test_create_port_pair_group_all_fields(self): - portpairgroup_id = _uuid() - data = {'port_pair_group': { - 'description': 'desc', - 'name': 'test1', - 'port_pairs': [], - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_pair_group(data) - return_value = copy.copy(expected_data['port_pair_group']) - return_value.update({'id': portpairgroup_id}) - instance = self.plugin.return_value - instance.create_port_pair_group.return_value = return_value - res = self.api.post( - _get_path(PORT_PAIR_GROUP_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_pair_group.assert_called_with( - mock.ANY, - port_pair_group=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_pair_group', res) - self.assertEqual(return_value, res['port_pair_group']) - - def test_create_port_pair_group_nonuuid_port_pairs(self): - data = {'port_pair_group': { - 'port_pairs': ['nouuid'], - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_PAIR_GROUP_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_pair_group_list(self): - portpairgroup_id = _uuid() - return_value = [{ - 'tenant_id': _uuid(), - 'id': portpairgroup_id - }] - instance = self.plugin.return_value - instance.get_port_pair_groups.return_value = return_value - - res = self.api.get( - _get_path(PORT_PAIR_GROUP_PATH, fmt=self.fmt)) - - instance.get_port_pair_groups.assert_called_with( - mock.ANY, - fields=mock.ANY, - filters=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_pair_groups', res) - self.assertEqual(res['port_pair_groups'], return_value) - - def test_port_pair_group_get(self): - portpairgroup_id = _uuid() - return_value = { - 'tenant_id': _uuid(), - 'id': portpairgroup_id - } - - instance = self.plugin.return_value - instance.get_port_pair_group.return_value = return_value - - res = self.api.get(_get_path(PORT_PAIR_GROUP_PATH, - id=portpairgroup_id, fmt=self.fmt)) - - instance.get_port_pair_group.assert_called_with( - mock.ANY, - portpairgroup_id, - fields=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_pair_group', res) - self.assertEqual(return_value, res['port_pair_group']) - - def test_port_pair_group_update(self): - portpairgroup_id = _uuid() - update_data = {'port_pair_group': { - 'name': 'new_name', - 'description': 'new_desc', - 'port_pairs': [_uuid()] - }} - return_value = { - 'tenant_id': _uuid(), - 'id': portpairgroup_id - } - - instance = self.plugin.return_value - instance.update_port_pair_group.return_value = return_value - - res = self.api.put( - _get_path( - PORT_PAIR_GROUP_PATH, id=portpairgroup_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_port_pair_group.assert_called_with( - mock.ANY, portpairgroup_id, - port_pair_group=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_pair_group', res) - self.assertEqual(res['port_pair_group'], return_value) - - def test_port_pair_group_update_nonuuid_port_pairs(self): - portpairgroup_id = _uuid() - data = {'port_pair_group': { - 'port_pairs': ['nouuid'] - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(PORT_PAIR_GROUP_PATH, id=portpairgroup_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_pair_group_delete(self): - self._test_entity_delete('port_pair_group') - - def _get_expected_port_pair(self, data): - return {'port_pair': { - 'name': data['port_pair'].get('name') or '', - 'description': data['port_pair'].get('description') or '', - 'ingress': data['port_pair']['ingress'], - 'egress': data['port_pair']['egress'], - 'service_function_parameters': data['port_pair'].get( - 'service_function_parameters') or {'correlation': None}, - 'tenant_id': data['port_pair']['tenant_id'] - }} - - def test_create_port_pair(self): - portpair_id = _uuid() - data = {'port_pair': { - 'ingress': _uuid(), - 'egress': _uuid(), - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_pair(data) - return_value = copy.copy(expected_data['port_pair']) - return_value.update({'id': portpair_id}) - instance = self.plugin.return_value - instance.create_port_pair.return_value = return_value - res = self.api.post(_get_path(PORT_PAIR_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_pair.assert_called_with( - mock.ANY, - port_pair=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_pair', res) - self.assertEqual(return_value, res['port_pair']) - - def test_create_port_pair_all_fields(self): - portpair_id = _uuid() - data = {'port_pair': { - 'description': 'desc', - 'name': 'test1', - 'ingress': _uuid(), - 'egress': _uuid(), - 'service_function_parameters': {'correlation': None}, - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_pair(data) - return_value = copy.copy(expected_data['port_pair']) - return_value.update({'id': portpair_id}) - instance = self.plugin.return_value - instance.create_port_pair.return_value = return_value - res = self.api.post(_get_path(PORT_PAIR_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_pair.assert_called_with( - mock.ANY, - port_pair=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_pair', res) - self.assertEqual(return_value, res['port_pair']) - - def test_create_port_pair_non_service_function_parameters(self): - portpair_id = _uuid() - data = {'port_pair': { - 'ingress': _uuid(), - 'egress': _uuid(), - 'service_function_parameters': None, - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_pair(data) - return_value = copy.copy(expected_data['port_pair']) - return_value.update({'id': portpair_id}) - instance = self.plugin.return_value - instance.create_port_pair.return_value = return_value - res = self.api.post(_get_path(PORT_PAIR_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_pair.assert_called_with( - mock.ANY, - port_pair=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_pair', res) - self.assertEqual(return_value, res['port_pair']) - - def test_create_port_pair_empty_service_function_parameters(self): - portpair_id = _uuid() - data = {'port_pair': { - 'ingress': _uuid(), - 'egress': _uuid(), - 'service_function_parameters': {}, - 'tenant_id': _uuid() - }} - expected_data = self._get_expected_port_pair(data) - return_value = copy.copy(expected_data['port_pair']) - return_value.update({'id': portpair_id}) - instance = self.plugin.return_value - instance.create_port_pair.return_value = return_value - res = self.api.post(_get_path(PORT_PAIR_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_port_pair.assert_called_with( - mock.ANY, - port_pair=expected_data) - self.assertEqual(res.status_int, exc.HTTPCreated.code) - res = self.deserialize(res) - self.assertIn('port_pair', res) - self.assertEqual(return_value, res['port_pair']) - - def test_create_port_pair_invalid_service_function_parameters(self): - data = {'port_pair': { - 'ingress': _uuid(), - 'egress': _uuid(), - 'service_function_parameters': {'abc': 'def'}, - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_PAIR_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_port_pair_nouuid_ingress(self): - data = {'port_pair': { - 'ingress': 'abc', - 'egress': _uuid(), - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_PAIR_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_create_port_pair_nouuid_egress(self): - data = {'port_pair': { - 'egress': 'abc', - 'ingress': _uuid(), - 'tenant_id': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.post, - _get_path(PORT_PAIR_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_pair_list(self): - portpair_id = _uuid() - return_value = [{ - 'tenant_id': _uuid(), - 'id': portpair_id - }] - instance = self.plugin.return_value - instance.get_port_pairs.return_value = return_value - - res = self.api.get(_get_path(PORT_PAIR_PATH, fmt=self.fmt)) - - instance.get_port_pairs.assert_called_with( - mock.ANY, - fields=mock.ANY, - filters=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_pairs', res) - self.assertEqual(res['port_pairs'], return_value) - - def test_port_pair_get(self): - portpair_id = _uuid() - return_value = { - 'tenant_id': _uuid(), - 'id': portpair_id - } - - instance = self.plugin.return_value - instance.get_port_pair.return_value = return_value - - res = self.api.get(_get_path(PORT_PAIR_PATH, - id=portpair_id, fmt=self.fmt)) - - instance.get_port_pair.assert_called_with( - mock.ANY, - portpair_id, - fields=mock.ANY - ) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_pair', res) - self.assertEqual(return_value, res['port_pair']) - - def test_port_pair_update(self): - portpair_id = _uuid() - update_data = {'port_pair': { - 'name': 'new_name', - 'description': 'new_desc' - }} - return_value = { - 'tenant_id': _uuid(), - 'id': portpair_id - } - - instance = self.plugin.return_value - instance.update_port_pair.return_value = return_value - - res = self.api.put(_get_path(PORT_PAIR_PATH, id=portpair_id, - fmt=self.fmt), - self.serialize(update_data)) - - instance.update_port_pair.assert_called_with( - mock.ANY, portpair_id, - port_pair=update_data) - self.assertEqual(res.status_int, exc.HTTPOk.code) - res = self.deserialize(res) - self.assertIn('port_pair', res) - self.assertEqual(res['port_pair'], return_value) - - def test_port_pair_update_service_function_parameters(self): - portpair_id = _uuid() - data = {'port_pair': { - 'service_function_parameters': None - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(PORT_PAIR_PATH, id=portpair_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_pair_update_ingress(self): - portpair_id = _uuid() - data = {'port_pair': { - 'ingress': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(PORT_PAIR_PATH, id=portpair_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_pair_update_egress(self): - portpair_id = _uuid() - data = {'port_pair': { - 'egress': _uuid() - }} - self.assertRaises( - webtest.app.AppError, - self.api.put, - _get_path(PORT_PAIR_PATH, id=portpair_id, - fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - - def test_port_pair_delete(self): - self._test_entity_delete('port_pair') diff --git a/networking_sfc/tests/unit/services/__init__.py b/networking_sfc/tests/unit/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/services/flowclassifier/__init__.py b/networking_sfc/tests/unit/services/flowclassifier/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/services/flowclassifier/test_driver_manager.py b/networking_sfc/tests/unit/services/flowclassifier/test_driver_manager.py deleted file mode 100644 index 56dd991..0000000 --- a/networking_sfc/tests/unit/services/flowclassifier/test_driver_manager.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import contextlib -import mock -import pkg_resources -import six -import stevedore - -from oslo_config import cfg - -from neutron.tests import base - -from networking_sfc.services.flowclassifier.common import config as fc_config -from networking_sfc.services.flowclassifier.common import exceptions as fc_exc -from networking_sfc.services.flowclassifier import driver_manager as fc_driver - - -class DriverManagerTestCase(base.BaseTestCase): - def setUp(self): - super(DriverManagerTestCase, self).setUp() - - @contextlib.contextmanager - def driver_manager_context(self, drivers): - cfg.CONF.register_opts(fc_config.FLOWCLASSIFIER_DRIVER_OPTS, - 'flowclassifier') - backup_driver_names = cfg.CONF.flowclassifier.drivers - driver_names = [ - driver_name for driver_name in six.iterkeys(drivers) - ] - cfg.CONF.set_override('drivers', driver_names, 'flowclassifier') - iter_entry_points = pkg_resources.iter_entry_points - find_entry_points = stevedore.ExtensionManager._find_entry_points - pkg_resources.iter_entry_points = mock.Mock() - stevedore.ExtensionManager._find_entry_points = mock.Mock() - driver_entry_points = [] - for driver_name in driver_names: - driver_class = mock.Mock() - ep = mock.Mock() - ep.name = driver_name - ep.resolve.return_value = driver_class - driver_class.return_value = drivers[driver_name] - drivers[driver_name].native_bulk_support = True - driver_entry_points.append(ep) - pkg_resources.iter_entry_points.return_value = driver_entry_points - stevedore.ExtensionManager._find_entry_points.return_value = ( - driver_entry_points - ) - yield fc_driver.FlowClassifierDriverManager() - cfg.CONF.set_override('drivers', backup_driver_names, 'flowclassifier') - pkg_resources.iter_entry_points = iter_entry_points - stevedore.ExtensionManager._find_entry_points = find_entry_points - - def test_initialize_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - manager.initialize() - mock_driver1.initialize.assert_called_once_with() - mock_driver2.initialize.assert_called_once_with() - - def test_create_flow_classifier_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.create_flow_classifier(mocked_context) - mock_driver1.create_flow_classifier.assert_called_once_with( - mocked_context) - mock_driver2.create_flow_classifier.assert_called_once_with( - mocked_context) - - def test_create_flow_classifier_exception(self): - mock_driver = mock.Mock() - mock_driver.create_flow_classifier = mock.Mock( - side_effect=fc_exc.FlowClassifierException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - fc_exc.FlowClassifierDriverError, - manager.create_flow_classifier, mocked_context - ) - - def test_update_flow_classifier_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.update_flow_classifier(mocked_context) - mock_driver1.update_flow_classifier.assert_called_once_with( - mocked_context) - mock_driver2.update_flow_classifier.assert_called_once_with( - mocked_context) - - def test_update_flow_classifier_exception(self): - mock_driver = mock.Mock() - mock_driver.update_flow_classifier = mock.Mock( - side_effect=fc_exc.FlowClassifierException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - fc_exc.FlowClassifierDriverError, - manager.update_flow_classifier, mocked_context - ) - - def test_delete_flow_classifier_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.delete_flow_classifier(mocked_context) - mock_driver1.delete_flow_classifier.assert_called_once_with( - mocked_context) - mock_driver2.delete_flow_classifier.assert_called_once_with( - mocked_context) - - def test_delete_flow_classifier_exception(self): - mock_driver = mock.Mock() - mock_driver.delete_flow_classifier = mock.Mock( - side_effect=fc_exc.FlowClassifierException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - fc_exc.FlowClassifierDriverError, - manager.delete_flow_classifier, mocked_context - ) diff --git a/networking_sfc/tests/unit/services/flowclassifier/test_plugin.py b/networking_sfc/tests/unit/services/flowclassifier/test_plugin.py deleted file mode 100644 index 2c814f8..0000000 --- a/networking_sfc/tests/unit/services/flowclassifier/test_plugin.py +++ /dev/null @@ -1,168 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import mock - -from networking_sfc.services.flowclassifier.common import context as fc_ctx -from networking_sfc.services.flowclassifier.common import exceptions as fc_exc -from networking_sfc.tests.unit.db import test_flowclassifier_db - -FLOWCLASSIFIER_PLUGIN_KLASS = ( - "networking_sfc.services.flowclassifier." - "plugin.FlowClassifierPlugin" -) - - -class FlowClassifierPluginTestCase( - test_flowclassifier_db.FlowClassifierDbPluginTestCase -): - def setUp( - self, core_plugin=None, flowclassifier_plugin=None, ext_mgr=None - ): - if not flowclassifier_plugin: - flowclassifier_plugin = FLOWCLASSIFIER_PLUGIN_KLASS - self.driver_manager_p = mock.patch( - 'networking_sfc.services.flowclassifier.driver_manager.' - 'FlowClassifierDriverManager' - ) - self.fake_driver_manager_class = self.driver_manager_p.start() - self.fake_driver_manager = mock.Mock() - self.fake_driver_manager_class.return_value = self.fake_driver_manager - self.plugin_context = None - super(FlowClassifierPluginTestCase, self).setUp( - core_plugin=core_plugin, - flowclassifier_plugin=flowclassifier_plugin, - ext_mgr=ext_mgr - ) - - def _record_context(self, plugin_context): - self.plugin_context = plugin_context - - def test_create_flow_classifier_driver_manager_called(self): - self.fake_driver_manager.create_flow_classifier = mock.Mock( - side_effect=self._record_context) - with self.flow_classifier(flow_classifier={}) as fc: - driver_manager = self.fake_driver_manager - driver_manager.create_flow_classifier.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, fc_ctx.FlowClassifierContext - ) - self.assertIn('flow_classifier', fc) - self.assertEqual( - self.plugin_context.current, fc['flow_classifier']) - - def test_create_flow_classifier_driver_manager_exception(self): - self.fake_driver_manager.create_flow_classifier = mock.Mock( - side_effect=fc_exc.FlowClassifierDriverError( - method='create_flow_classifier' - ) - ) - self._create_flow_classifier( - self.fmt, {}, expected_res_status=500) - self._test_list_resources('flow_classifier', []) - driver_manager = self.fake_driver_manager - driver_manager.delete_flow_classifier.assert_called_once_with( - mock.ANY - ) - - def test_update_flow_classifier_driver_manager_called(self): - self.fake_driver_manager.update_flow_classifier = mock.Mock( - side_effect=self._record_context) - with self.flow_classifier(flow_classifier={'name': 'test1'}) as fc: - req = self.new_update_request( - 'flow_classifiers', {'flow_classifier': {'name': 'test2'}}, - fc['flow_classifier']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - driver_manager = self.fake_driver_manager - driver_manager.update_flow_classifier.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, fc_ctx.FlowClassifierContext - ) - self.assertIn('flow_classifier', fc) - self.assertIn('flow_classifier', res) - self.assertEqual( - self.plugin_context.current, res['flow_classifier']) - self.assertEqual( - self.plugin_context.original, fc['flow_classifier']) - - def test_update_flow_classifier_driver_manager_exception(self): - self.fake_driver_manager.update_flow_classifier = mock.Mock( - side_effect=fc_exc.FlowClassifierDriverError( - method='update_flow_classifier' - ) - ) - with self.flow_classifier(flow_classifier={ - 'name': 'test1' - }) as fc: - self.assertIn('flow_classifier', fc) - original_flow_classifier = fc['flow_classifier'] - req = self.new_update_request( - 'flow_classifiers', {'flow_classifier': {'name': 'test2'}}, - fc['flow_classifier']['id'] - ) - updated_flow_classifier = copy.copy(original_flow_classifier) - updated_flow_classifier['name'] = 'test2' - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - res = self._list('flow_classifiers') - self.assertIn('flow_classifiers', res) - self.assertItemsEqual( - res['flow_classifiers'], [updated_flow_classifier]) - - def test_delete_flow_classifer_driver_manager_called(self): - self.fake_driver_manager.delete_flow_classifier = mock.Mock( - side_effect=self._record_context) - with self.flow_classifier( - flow_classifier={}, do_delete=False - ) as fc: - req = self.new_delete_request( - 'flow_classifiers', fc['flow_classifier']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - driver_manager = self.fake_driver_manager - driver_manager.delete_flow_classifier.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, fc_ctx.FlowClassifierContext - ) - self.assertIn('flow_classifier', fc) - self.assertEqual( - self.plugin_context.current, fc['flow_classifier']) - - def test_delete_flow_classifier_driver_manager_exception(self): - self.fake_driver_manager.delete_flow_classifier = mock.Mock( - side_effect=fc_exc.FlowClassifierDriverError( - method='delete_flow_classifier' - ) - ) - with self.flow_classifier(flow_classifier={ - 'name': 'test1' - }, do_delete=False) as fc: - req = self.new_delete_request( - 'flow_classifiers', fc['flow_classifier']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - self._test_list_resources('flow_classifier', [fc]) diff --git a/networking_sfc/tests/unit/services/sfc/__init__.py b/networking_sfc/tests/unit/services/sfc/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/services/sfc/agent/__init__.py b/networking_sfc/tests/unit/services/sfc/agent/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/services/sfc/agent/test-agent.py b/networking_sfc/tests/unit/services/sfc/agent/test-agent.py deleted file mode 100644 index 113c343..0000000 --- a/networking_sfc/tests/unit/services/sfc/agent/test-agent.py +++ /dev/null @@ -1,4012 +0,0 @@ -# Copyright 2015 Huawei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock -import six - -from neutron.agent.common import ovs_lib -from neutron.agent.common import utils -from neutron.agent import rpc as agent_rpc -from neutron import context -from neutron.tests import base - -from networking_sfc.services.sfc.agent import ( - ovs_sfc_agent as agent) -from networking_sfc.services.sfc.agent import br_int -from networking_sfc.services.sfc.agent import br_phys -from networking_sfc.services.sfc.agent import br_tun -from networking_sfc.services.sfc.common import ovs_ext_lib - - -class OVSSfcAgentTestCase(base.BaseTestCase): - def setUp(self): - super(OVSSfcAgentTestCase, self).setUp() - mock.patch( - 'neutron.agent.common.ovs_lib.OVSBridge.get_ports_attributes', - return_value=[] - ).start() - mock.patch( - 'neutron.agent.common.ovs_lib.BaseOVS.config', - new_callable=mock.PropertyMock, - return_value={} - ).start() - self.executed_cmds = [] - self.node_flowrules = [] - self.backup_plugin_rpc = agent.SfcPluginApi - self.plugin_rpc = mock.Mock() - self.plugin_rpc.get_flowrules_by_host_portid = mock.Mock( - side_effect=self.mock_get_flowrules_by_host_portid - ) - self.plugin_rpc.get_all_src_node_flowrules = mock.Mock( - side_effect=self.mock_get_all_src_node_flowrules - ) - agent.SfcPluginApi = mock.Mock( - return_value=self.plugin_rpc - ) - self.create_consumers = mock.patch.object( - agent_rpc, "create_consumers", - self.mock_create_consumers - ) - self.create_consumers.start() - self.execute = mock.patch.object( - utils, "execute", self.mock_execute, - spec=utils.execute) - self.execute.start() - self.added_flows = [] - self.add_flow = mock.patch.object( - ovs_lib.OVSBridge, "add_flow", self.mock_add_flow - ) - self.add_flow.start() - self.deleted_flows = [] - self.delete_flows = mock.patch.object( - ovs_lib.OVSBridge, "delete_flows", self.mock_delete_flows - ) - self.delete_flows.start() - self.int_patch = 1 - self.tun_patch = 2 - self.default_port_mapping = { - 'patch-int': { - 'ofport': self.int_patch - }, - 'patch-tun': { - 'ofport': self.tun_patch - } - } - self.port_mapping = {} - self.get_vif_port_by_id = mock.patch.object( - ovs_lib.OVSBridge, "get_vif_port_by_id", - self.mock_get_vif_port_by_id - ) - self.get_vif_port_by_id.start() - self.get_port_ofport = mock.patch.object( - ovs_lib.OVSBridge, "get_port_ofport", - self.mock_get_port_ofport - ) - self.get_port_ofport.start() - self.set_secure_mode = mock.patch.object( - ovs_lib.OVSBridge, "set_secure_mode", - self.mock_set_secure_mode - ) - self.set_secure_mode.start() - self.protocols = [] - self.set_protocols = mock.patch.object( - ovs_lib.OVSBridge, "set_protocols", - self.mock_set_protocols - ) - self.set_protocols.start() - self.del_controller = mock.patch.object( - ovs_lib.OVSBridge, "del_controller", - self.mock_del_controller - ) - self.del_controller.start() - self.get_bridges = mock.patch.object( - ovs_lib.BaseOVS, "get_bridges", - self.mock_get_bridges - ) - self.get_bridges.start() - self.get_vif_ports = mock.patch.object( - ovs_lib.OVSBridge, "get_vif_ports", - self.mock_get_vif_ports - ) - self.get_vif_ports.start() - self.get_ports_attributes = mock.patch.object( - ovs_lib.OVSBridge, "get_ports_attributes", - self.mock_get_ports_attributes - ) - self.get_ports_attributes.start() - self.delete_port = mock.patch.object( - ovs_lib.OVSBridge, "delete_port", - self.mock_delete_port - ) - self.delete_port.start() - self.create = mock.patch.object( - ovs_lib.OVSBridge, "create", - self.mock_create - ) - self.create.start() - self.add_port = mock.patch.object( - ovs_lib.OVSBridge, "add_port", - self.mock_add_port - ) - self.add_port.start() - self.bridge_exists = mock.patch.object( - ovs_lib.BaseOVS, "bridge_exists", - self.mock_bridge_exists - ) - self.bridge_exists.start() - self.port_exists = mock.patch.object( - ovs_lib.BaseOVS, "port_exists", - self.mock_port_exists - ) - self.port_exists.start() - self.apply_flows = mock.patch.object( - ovs_lib.DeferredOVSBridge, "apply_flows", - self.mock_apply_flows - ) - self.apply_flows.start() - self.group_mapping = {} - self.deleted_groups = [] - self.dump_group_for_id = mock.patch.object( - ovs_ext_lib.OVSBridgeExt, "dump_group_for_id", - self.mock_dump_group_for_id - ) - self.dump_group_for_id.start() - self.add_group = mock.patch.object( - ovs_ext_lib.OVSBridgeExt, "add_group", - self.mock_add_group - ) - self.add_group.start() - self.mod_group = mock.patch.object( - ovs_ext_lib.OVSBridgeExt, "mod_group", - self.mock_mod_group - ) - self.mod_group.start() - self.delete_group = mock.patch.object( - ovs_ext_lib.OVSBridgeExt, "delete_group", - self.mock_delete_group - ) - self.delete_group.start() - self.local_ip = '10.0.0.1' - self.bridge_classes = { - 'br_int': br_int.OVSIntegrationBridge, - 'br_phys': br_phys.OVSPhysicalBridge, - 'br_tun': br_tun.OVSTunnelBridge, - } - self.context = context.get_admin_context_without_session() - self.init_agent() - - def init_agent(self): - self.added_flows = [] - self.deleted_flows = [] - self.group_mapping = {} - self.deleted_groups = [] - self.agent = agent.OVSSfcAgent( - self.bridge_classes, - 'br-int', - 'br-tun', - self.local_ip, - {}, - 2, - tunnel_types=['gre', 'vxlan'] - ) - - def mock_create_consumers( - self, endpoints, prefix, topic_details, start_listening=True - ): - self.added_flows = [] - self.deleted_flows = [] - return mock.Mock() - - def mock_delete_group(self, group_id): - if group_id == 'all': - self.group_mapping = {} - else: - if group_id in self.group_mapping: - del self.group_mapping[group_id] - else: - self.deleted_groups.append(group_id) - - def mock_mod_group(self, group_id, **kwargs): - kwargs['group_id'] = group_id - self.group_mapping[group_id] = kwargs - - def mock_add_group(self, group_id, **kwargs): - kwargs['group_id'] = group_id - self.group_mapping[group_id] = kwargs - - def mock_dump_group_for_id(self, group_id): - if group_id in self.group_mapping: - group_list = [] - group = self.group_mapping[group_id] - for group_key, group_value in six.iteritems(group): - group_list.append('%s=%s' % (group_key, group_value)) - return ' '.join(group_list) - else: - return '' - - def mock_set_secure_mode(self): - pass - - def mock_set_protocols(self, protocols): - self.protocols = protocols - - def mock_del_controller(self): - pass - - def mock_get_bridges(self): - return ['br-int', 'br-tun'] - - def mock_get_port_ofport(self, port_name): - for port_id, port_values in six.iteritems(self.port_mapping): - if port_values['port_name'] == port_name: - return port_values['ofport'] - if port_name in self.default_port_mapping: - return self.default_port_mapping[port_name]['ofport'] - return ovs_lib.INVALID_OFPORT - - def mock_add_port(self, port_name, *interface_attr_tuples): - return self.mock_get_port_ofport(port_name) - - def mock_bridge_exists(self, bridge_name): - return True - - def mock_port_exists(self, port_name): - return True - - def mock_apply_flows(self): - pass - - def mock_get_vif_port_by_id(self, port_id): - if port_id in self.port_mapping: - port_values = self.port_mapping[port_id] - return ovs_lib.VifPort( - port_values['port_name'], - port_values['ofport'], - port_id, - port_values['vif_mac'], - self.agent.int_br - ) - - def mock_get_vif_ports(self): - vif_ports = [] - for port_id, port_values in six.iteritems(self.port_mapping): - vif_ports.append( - ovs_lib.VifPort( - port_values['port_name'], - port_values['ofport'], - port_id, - port_values['vif_mac'], - self.agent.int_br - ) - ) - return vif_ports - - def mock_get_ports_attributes( - self, table, columns=None, ports=None, - check_error=True, log_errors=True, - if_exists=False - ): - port_infos = [] - for port_id, port_values in six.iteritems(self.port_mapping): - port_info = {} - if columns: - if 'name' in columns: - port_info['name'] = port_values['port_name'] - if 'ofport' in columns: - port_info['ofport'] = port_values['ofport'] - if 'extenal_ids' in columns: - port_info['extenal_ids'] = { - 'iface-id': port_id, - 'attached-mac': port_values['vif_mac'] - } - if 'other_config' in columns: - port_info['other_config'] = {} - if 'tag' in columns: - port_info['tag'] = [] - else: - port_info = { - 'name': port_values['port_name'], - 'ofport': port_values['ofport'], - 'extenal_ids': { - 'iface-id': port_id, - 'attached-mac': port_values['vif_mac'] - }, - 'other_config': {}, - 'tag': [] - } - if ports: - if port_values['port_name'] in ports: - port_infos.append(port_info) - else: - port_infos.append(port_info) - return port_infos - - def mock_delete_port(self, port_name): - found_port_id = None - for port_id, port_values in six.iteritems(self.port_mapping): - if port_values['port_name'] == port_name: - found_port_id = port_id - if found_port_id: - del self.port_mapping[found_port_id] - - def mock_create(self, secure_mode=False): - pass - - def mock_add_flow(self, *args, **kwargs): - if kwargs not in self.added_flows: - self.added_flows.append(kwargs) - - def mock_delete_flows(self, *args, **kwargs): - if kwargs not in self.deleted_flows: - self.deleted_flows.append(kwargs) - - def mock_get_flowrules_by_host_portid(self, context, port_id): - return [ - flowrule - for flowrule in self.node_flowrules - if ( - flowrule['ingress'] == port_id or - flowrule['egress'] == port_id - ) - ] - - def mock_get_all_src_node_flowrules(self, context): - return [ - flowrule - for flowrule in self.node_flowrules - if ( - flowrule['node_type'] == 'src_node' and - flowrule['egress'] is None - ) - ] - - def mock_execute(self, cmd, *args, **kwargs): - self.executed_cmds.append(' '.join(cmd)) - - def tearDown(self): - agent.SfcPluginApi = self.backup_plugin_rpc - self.create_consumers.stop() - self.execute.stop() - self.add_flow.stop() - self.delete_flows.stop() - self.get_vif_port_by_id.stop() - self.get_port_ofport.stop() - self.set_secure_mode.stop() - self.set_protocols.stop() - self.del_controller.stop() - self.get_bridges.stop() - self.get_vif_ports.stop() - self.get_ports_attributes.stop() - self.delete_port.stop() - self.create.stop() - self.add_port.stop() - self.bridge_exists.stop() - self.port_exists.stop() - self.apply_flows.stop() - self.dump_group_for_id.stop() - self.add_group.stop() - self.mod_group.stop() - self.delete_group.stop() - self.node_flowrules = [] - self.added_flows = [] - self.deleted_flows = [] - self.group_mapping = {} - self.deleted_groups = [] - self.port_mapping = {} - super(OVSSfcAgentTestCase, self).tearDown() - - def test_update_empty_flow_rules(self): - self.port_mapping = { - 'dd7374b9-a6ac-4a66-a4a6-7d3dee2a1579': { - 'port_name': 'src_port', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '2f1d2140-42ce-4979-9542-7ef25796e536': { - 'port_name': 'dst_port', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - } - } - self.agent.update_flow_rules( - self.context, flowrule_entries={ - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.added_flows, [{ - 'actions': 'resubmit(,%d)' % agent.SF_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI, - 'table': 0 - }, { - 'actions': 'resubmit(,%d)' % agent.FWD_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI - }, { - 'actions': 'output:%d' % self.int_patch, - 'priority': 0, - 'table': agent.FWD_SELECTOR - }, { - 'actions': 'resubmit(,%d)' % agent.GRP_SELECTOR, - 'in_port': self.int_patch, - 'priority': agent.PC_DEF_PRI, - 'table': agent.FWD_SELECTOR - }] - ) - self.assertEqual( - self.group_mapping, {} - ) - - def test_update_flow_rules_port_pair(self): - self.port_mapping = { - 'dd7374b9-a6ac-4a66-a4a6-7d3dee2a1579': { - 'port_name': 'src_port', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '2f1d2140-42ce-4979-9542-7ef25796e536': { - 'port_name': 'dst_port', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - } - } - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': u'dd7374b9-a6ac-4a66-a4a6-7d3dee2a1579', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 75, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:fd:b2', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'2f1d2140-42ce-4979-9542-7ef25796e536', - 'next_group_id': None, - 'host_id': u'test1', - 'nsp': 256, - 'portchain_id': u'84c1411f-7a94-4b4f-9a8b-ad9607c67c76', - 'add_fcs': [], - 'id': '611bdc42-12b3-4639-8faf-83da4e6403f7' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.added_flows, [{ - 'actions': 'resubmit(,%d)' % agent.SF_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI, - 'table': 0 - }, { - 'actions': 'resubmit(,%d)' % agent.FWD_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI - }, { - 'actions': 'output:%d' % self.int_patch, - 'priority': 0, - 'table': agent.FWD_SELECTOR - }, { - 'actions': 'resubmit(,%d)' % agent.GRP_SELECTOR, - 'in_port': self.int_patch, - 'priority': agent.PC_DEF_PRI, - 'table': agent.FWD_SELECTOR - }, { - 'actions': 'pop_mpls:0x0800,output:6', - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': agent.SF_SELECTOR - }] - ) - self.assertEqual( - self.group_mapping, {} - ) - - def test_update_flow_rules_flow_classifiers(self): - self.port_mapping = { - 'e1229670-2a07-450d-bdc9-34e71c301206': { - 'port_name': 'src_port', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '9bedd01e-c216-4dfd-b48e-fbd5c8212ba4': { - 'port_name': 'dst_port', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - } - } - - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 43, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:72:05', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'src_node', - 'egress': u'9bedd01e-c216-4dfd-b48e-fbd5c8212ba4', - 'next_group_id': 1, - 'host_id': u'test1', - 'nsp': 256, - 'portchain_id': u'8cba323e-5e67-4df0-a4b0-7e1ef486a656', - 'add_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': u'10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - 'e1229670-2a07-450d-bdc9-34e71c301206'), - 'l7_parameters': {}, - 'source_port_range_max': 200, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': u'IPv4', - 'destination_port_range_max': 400, - 'logical_source_port': ( - '9bedd01e-c216-4dfd-b48e-fbd5c8212ba4') - }], - 'id': '611bdc42-12b3-4639-8faf-83da4e6403f7' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': 'e1229670-2a07-450d-bdc9-34e71c301206', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 43, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:c5:f3', - 'network_type': 'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': u'test2', - 'nsp': 256, - 'portchain_id': '8cba323e-5e67-4df0-a4b0-7e1ef486a656', - 'add_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': u'10.200.0.0/16', - 'protocol': 'tcp', - 'logical_destination_port': ( - 'e1229670-2a07-450d-bdc9-34e71c301206'), - 'l7_parameters': {}, - 'source_port_range_max': 200, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': 'IPv4', - 'destination_port_range_max': 400, - 'logical_source_port': ( - '9bedd01e-c216-4dfd-b48e-fbd5c8212ba4') - }], - 'id': '611bdc42-12b3-4639-8faf-83da4e6403f8' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.added_flows, [{ - 'actions': 'resubmit(,%d)' % agent.SF_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI, - 'table': 0 - }, { - 'actions': 'resubmit(,%d)' % agent.FWD_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI - }, { - 'actions': 'output:%d' % self.int_patch, - 'priority': 0, - 'table': agent.FWD_SELECTOR - }, { - 'actions': 'resubmit(,%d)' % agent.GRP_SELECTOR, - 'in_port': self.int_patch, - 'priority': agent.PC_DEF_PRI, - 'table': agent.FWD_SELECTOR - }, { - 'actions': 'pop_mpls:0x0800,output:6', - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': agent.SF_SELECTOR - }] - ) - self.assertEqual( - self.group_mapping, {} - ) - - def test_update_flow_rules_flow_classifiers_port_pairs(self): - self.port_mapping = { - '8768d2b3-746d-4868-ae0e-e81861c2b4e6': { - 'port_name': 'port1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '29e38fb2-a643-43b1-baa8-a86596461cd5': { - 'port_name': 'port2', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - '82a575e0-6a6e-46ba-a5fc-692407839a85': { - 'port_name': 'port3', - 'ofport': 60, - 'vif_mac': '00:01:02:03:06:09' - }, - '93466f5d-252e-4552-afc6-5fb3f6019f76': { - 'port_name': 'port4', - 'ofport': 25, - 'vif_mac': '00:01:02:03:06:10' - } - } - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.2', - 'ingress': '8768d2b3-746d-4868-ae0e-e81861c2b4e6', - 'weight': 1, - 'mac_address': '12:34:56:78:cf:23' - }], - 'del_fcs': [], - 'segment_id': 33, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:ed:01', - 'network_type': 'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'src_node', - 'egress': '29e38fb2-a643-43b1-baa8-a86596461cd5', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': 'b9570dc9-822b-41fc-a27c-d915a21a3fe8', - 'add_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': u'10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - '82a575e0-6a6e-46ba-a5fc-692407839a85'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': '10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': 'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '29e38fb2-a643-43b1-baa8-a86596461cd5') - }], - 'id': '73e97aad-8c0f-44e3-bee0-c0a641b00b66' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': '82a575e0-6a6e-46ba-a5fc-692407839a85', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 33, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:a6:84', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': 'b9570dc9-822b-41fc-a27c-d915a21a3fe8', - 'add_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': '10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - '82a575e0-6a6e-46ba-a5fc-692407839a85'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': u'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '29e38fb2-a643-43b1-baa8-a86596461cd5') - }], - 'id': 'fa385d84-7d78-44e7-aa8d-7b4a279a14d7' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': '8768d2b3-746d-4868-ae0e-e81861c2b4e6', - 'next_hops': [{ - 'local_endpoint': '10.0.0.2', - 'ingress': '82a575e0-6a6e-46ba-a5fc-692407839a85', - 'weight': 1, - 'mac_address': '12:34:56:78:a6:84' - }], - 'del_fcs': [], - 'segment_id': 33, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:cf:23', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'sf_node', - 'egress': '93466f5d-252e-4552-afc6-5fb3f6019f76', - 'next_group_id': None, - 'host_id': 'test3', - 'nsp': 256, - 'portchain_id': 'b9570dc9-822b-41fc-a27c-d915a21a3fe8', - 'add_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': '10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - '82a575e0-6a6e-46ba-a5fc-692407839a85'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': u'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '29e38fb2-a643-43b1-baa8-a86596461cd5') - }], - 'id': '07cc65a8-e99b-4175-a2f1-69b87eb8090a' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.added_flows, [{ - 'actions': 'resubmit(,%d)' % agent.SF_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI, - 'table': 0 - }, { - 'actions': 'resubmit(,%d)' % agent.FWD_SELECTOR, - 'dl_type': 34887, - 'priority': agent.PC_DEF_PRI - }, { - 'actions': 'output:%d' % self.int_patch, - 'priority': 0, - 'table': agent.FWD_SELECTOR - }, { - 'actions': 'resubmit(,%d)' % agent.GRP_SELECTOR, - 'in_port': self.int_patch, - 'priority': agent.PC_DEF_PRI, - 'table': agent.FWD_SELECTOR - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 42, - 'nw_dst': u'10.200.0.0/16', - 'nw_proto': 6, - 'nw_src': u'10.100.0.0/16', - 'priority': 10, - 'table': 0, - 'tp_dst': '0x12c/0xffff', - 'tp_src': '0x64/0xffff' - }, { - 'actions': 'group:1', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 0, - 'table': agent.GRP_SELECTOR - }, { - 'actions': 'pop_mpls:0x0800,output:60', - 'dl_dst': '00:01:02:03:06:09', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': agent.SF_SELECTOR - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:a6:84,' - 'set_field:33->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65790, - 'nw_dst': u'10.200.0.0/16', - 'nw_proto': 6, - 'nw_src': u'10.100.0.0/16', - 'priority': 0, - 'table': agent.GRP_SELECTOR, - 'tp_dst': '0x12c/0xffff', - 'tp_src': '0x64/0xffff' - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 25, - 'nw_dst': u'10.200.0.0/16', - 'nw_proto': 6, - 'nw_src': u'10.100.0.0/16', - 'priority': agent.PC_DEF_PRI, - 'table': 0, - 'tp_dst': '0x12c/0xffff', - 'tp_src': '0x64/0xffff' - }, { - 'actions': 'pop_mpls:0x0800,output:6', - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': agent.SF_SELECTOR - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:cf:23,' - 'set_field:33->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - } - } - ) - - def test_update_flow_rules_flow_classifiers_multi_port_groups(self): - self.port_mapping = { - '6331a00d-779b-462b-b0e4-6a65aa3164ef': { - 'port_name': 'port1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '1ebf82cf-70f9-43fd-8b90-6546f7d13040': { - 'port_name': 'port2', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - '34032c43-5207-43bb-95cb-cf426266fa11': { - 'port_name': 'port3', - 'ofport': 60, - 'vif_mac': '00:01:02:03:06:09' - }, - 'eaeec782-4ee8-4c7f-8ecb-f759dab4c723': { - 'port_name': 'port4', - 'ofport': 25, - 'vif_mac': '00:01:02:03:06:10' - }, - 'f56df7aa-e521-41ce-9001-ed7bedb65c9e': { - 'port_name': 'port5', - 'ofport': 5, - 'vif_mac': '00:01:02:03:06:11' - }, - '15dc026d-0520-4f92-9841-1056e62fdcaa': { - 'port_name': 'port6', - 'ofport': 50, - 'vif_mac': '00:01:02:03:06:12' - }, - 'd98a48fe-4ef7-4aa6-89fa-02312e54c1bd': { - 'port_name': 'port7', - 'ofport': 4, - 'vif_mac': '00:01:02:03:06:13' - }, - 'd412d042-d8bc-4dd9-b2be-b29c7e8b2c1b': { - 'port_name': 'port8', - 'ofport': 8, - 'vif_mac': '00:01:02:03:06:14' - } - } - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.2', - 'ingress': '34032c43-5207-43bb-95cb-cf426266fa11', - 'weight': 1, - 'mac_address': '12:34:56:78:b0:88' - }], - 'del_fcs': [], - 'segment_id': 37, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:74:91', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'src_node', - 'egress': '6331a00d-779b-462b-b0e4-6a65aa3164ef', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': 'd0b48df7-47ab-4909-b864-9aae1a6ee6fb', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '1ebf82cf-70f9-43fd-8b90-6546f7d13040'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': 'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '6331a00d-779b-462b-b0e4-6a65aa3164ef') - }], - 'id': 'bbb1e50c-ecbb-400c-a7e9-8aed8f36993f' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 251, - 'ingress': '1ebf82cf-70f9-43fd-8b90-6546f7d13040', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 37, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:b7:0d', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': 'd0b48df7-47ab-4909-b864-9aae1a6ee6fb', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '1ebf82cf-s70f9-43fd-8b90-6546f7d13040'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '6331a00d-779b-462b-b0e4-6a65aa3164ef') - }], - 'id': '7ed75c14-2283-484a-97b8-30e23fbf7457' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': '34032c43-5207-43bb-95cb-cf426266fa11', - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'f56df7aa-e521-41ce-9001-ed7bedb65c9e', - 'weight': 1, - 'mac_address': u'12:34:56:78:b1:0d' - }], - 'del_fcs': [], - 'segment_id': 37, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:b0:88', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'eaeec782-4ee8-4c7f-8ecb-f759dab4c723', - 'next_group_id': 2, - 'host_id': u'test3', - 'nsp': 256, - 'portchain_id': u'd0b48df7-47ab-4909-b864-9aae1a6ee6fb', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '1ebf82cf-70f9-43fd-8b90-6546f7d13040'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '6331a00d-779b-462b-b0e4-6a65aa3164ef') - }], - 'id': 'f9fd9c7a-0100-43fb-aea9-30c67f2a731a' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': 'f56df7aa-e521-41ce-9001-ed7bedb65c9e', - 'next_hops': [{ - 'local_endpoint': '10.0.0.2', - 'ingress': 'd98a48fe-4ef7-4aa6-89fa-02312e54c1bd', - 'weight': 1, - 'mac_address': '12:34:56:78:4e:dd' - }], - 'del_fcs': [], - 'segment_id': 37, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:b1:0d', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'15dc026d-0520-4f92-9841-1056e62fdcaa', - 'next_group_id': 3, - 'host_id': u'test5', - 'nsp': 256, - 'portchain_id': u'd0b48df7-47ab-4909-b864-9aae1a6ee6fb', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '1ebf82cf-70f9-43fd-8b90-6546f7d13040'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '6331a00d-779b-462b-b0e4-6a65aa3164ef') - }], - 'id': '62f4bb35-1b4a-4cc4-bf07-f40ed5c2d6a7' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 252, - 'ingress': u'd98a48fe-4ef7-4aa6-89fa-02312e54c1bd', - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'1ebf82cf-70f9-43fd-8b90-6546f7d13040', - 'weight': 1, - 'mac_address': u'12:34:56:78:b7:0d' - }], - 'del_fcs': [], - 'segment_id': 37, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:4e:dd', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'd412d042-d8bc-4dd9-b2be-b29c7e8b2c1b', - 'next_group_id': None, - 'host_id': u'test7', - 'nsp': 256, - 'portchain_id': u'd0b48df7-47ab-4909-b864-9aae1a6ee6fb', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '1ebf82cf-70f9-43fd-8b90-6546f7d13040'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '6331a00d-779b-462b-b0e4-6a65aa3164ef') - }], - 'id': 'a535e740-02cc-47ef-aab1-7bcb1594db9b' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.added_flows, [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:%d' % self.int_patch, - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': self.int_patch, - 'priority': 10, - 'table': 30 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 6, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:1', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:42' - ), - 'dl_dst': '00:01:02:03:06:08', - 'dl_type': 34887, - 'mpls_label': 65788, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 25, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:2', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:60' - ), - 'dl_dst': '00:01:02:03:06:09', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65789,' - 'set_mpls_ttl:253,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 50, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:3', - 'dl_type': 34887, - 'mpls_label': 65789, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:5' - ), - 'dl_dst': '00:01:02:03:06:11', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:b7:0d,' - 'set_field:37->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65788, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65788,' - 'set_mpls_ttl:252,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 8, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:4' - ), - 'dl_dst': '00:01:02:03:06:13', - 'dl_type': 34887, - 'mpls_label': 65789, - 'priority': 1, - 'table': 5 - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:b0:88,' - 'set_field:37->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - }, - 2: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:b1:0d,' - 'set_field:37->tun_id,output:[]' - ), - 'group_id': 2, - 'type': 'select' - }, - 3: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:4e:dd,' - 'set_field:37->tun_id,output:[]' - ), - 'group_id': 3, - 'type': 'select' - } - } - ) - - def test_update_flow_rules_flow_classifiers_multi_port_pairs(self): - self.port_mapping = { - '9864d8e8-0aff-486e-8b84-7a8d20c017d4': { - 'port_name': 'port1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '21047d09-eaa7-4296-af56-b509e4a10853': { - 'port_name': 'port2', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - '38266cfe-cd42-413e-80ff-d0d0c74ad260': { - 'port_name': 'port3', - 'ofport': 60, - 'vif_mac': '00:01:02:03:06:09' - }, - '272be90c-b140-4e9d-8dd3-1993fbb3656c': { - 'port_name': 'port4', - 'ofport': 25, - 'vif_mac': '00:01:02:03:06:10' - }, - 'd1791c8d-a07a-4f35-bd52-b99395da0d76': { - 'port_name': 'port5', - 'ofport': 5, - 'vif_mac': '00:01:02:03:06:11' - }, - 'ed2804bd-d61a-49e7-9007-76d2540ae78a': { - 'port_name': 'port6', - 'ofport': 50, - 'vif_mac': '00:01:02:03:06:12' - }, - 'bdf4f759-ca35-4cf5-89ac-53da0d6b3fbf': { - 'port_name': 'port7', - 'ofport': 4, - 'vif_mac': '00:01:02:03:06:13' - }, - 'a55b9062-d3fa-4dc2-a4df-bb8b2a908c19': { - 'port_name': 'port8', - 'ofport': 8, - 'vif_mac': '00:01:02:03:06:14' - } - } - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'38266cfe-cd42-413e-80ff-d0d0c74ad260', - 'weight': 1, - 'mac_address': u'12:34:56:78:74:c1' - }, { - 'local_endpoint': u'10.0.0.2', - 'ingress': u'd1791c8d-a07a-4f35-bd52-b99395da0d76', - 'weight': 1, - 'mac_address': u'12:34:56:78:4f:6e' - }, { - 'local_endpoint': u'10.0.0.2', - 'ingress': u'bdf4f759-ca35-4cf5-89ac-53da0d6b3fbf', - 'weight': 1, - 'mac_address': u'12:34:56:78:d5:66' - }], - 'del_fcs': [], - 'segment_id': 51, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:9c:70', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'src_node', - 'egress': u'9864d8e8-0aff-486e-8b84-7a8d20c017d4', - 'next_group_id': 1, - 'host_id': u'test1', - 'nsp': 256, - 'portchain_id': u'3dddbb0c-5ac4-437c-9b62-ed7ddf8df37f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '21047d09-eaa7-4296-af56-b509e4a10853'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '9864d8e8-0aff-486e-8b84-7a8d20c017d4') - }], - 'id': '677dfe31-8566-4bd8-8a1e-5f8efd7a45eb' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': u'21047d09-eaa7-4296-af56-b509e4a10853', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 51, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:67:cb', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': u'test2', - 'nsp': 256, - 'portchain_id': u'3dddbb0c-5ac4-437c-9b62-ed7ddf8df37f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '21047d09-eaa7-4296-af56-b509e4a10853'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '9864d8e8-0aff-486e-8b84-7a8d20c017d4') - }], - 'id': '4f275568-38cb-45a1-a162-e0d1d4ef335d' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': u'38266cfe-cd42-413e-80ff-d0d0c74ad260', - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'21047d09-eaa7-4296-af56-b509e4a10853', - 'weight': 1, - 'mac_address': u'12:34:56:78:67:cb' - }], - 'del_fcs': [], - 'segment_id': 51, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:74:c1', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'272be90c-b140-4e9d-8dd3-1993fbb3656c', - 'next_group_id': None, - 'host_id': u'test3', - 'nsp': 256, - 'portchain_id': u'3dddbb0c-5ac4-437c-9b62-ed7ddf8df37f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '21047d09-eaa7-4296-af56-b509e4a10853'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '9864d8e8-0aff-486e-8b84-7a8d20c017d4') - }], - 'id': '48fd97b1-e166-4aff-906f-8096a48a7cb1' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': u'd1791c8d-a07a-4f35-bd52-b99395da0d76', - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'21047d09-eaa7-4296-af56-b509e4a10853', - 'weight': 1, - 'mac_address': u'12:34:56:78:67:cb' - }], - 'del_fcs': [], - 'segment_id': 51, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:4f:6e', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'ed2804bd-d61a-49e7-9007-76d2540ae78a', - 'next_group_id': None, - 'host_id': u'test5', - 'nsp': 256, - 'portchain_id': u'3dddbb0c-5ac4-437c-9b62-ed7ddf8df37f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '21047d09-eaa7-4296-af56-b509e4a10853'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '9864d8e8-0aff-486e-8b84-7a8d20c017d4') - }], - 'id': '48fd97b1-e166-4aff-906f-8096a48a7cb1' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': u'bdf4f759-ca35-4cf5-89ac-53da0d6b3fbf', - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'21047d09-eaa7-4296-af56-b509e4a10853', - 'weight': 1, - 'mac_address': u'12:34:56:78:67:cb' - }], - 'del_fcs': [], - 'segment_id': 51, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:d5:66', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'a55b9062-d3fa-4dc2-a4df-bb8b2a908c19', - 'next_group_id': None, - 'host_id': u'test7', - 'nsp': 256, - 'portchain_id': u'3dddbb0c-5ac4-437c-9b62-ed7ddf8df37f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '21047d09-eaa7-4296-af56-b509e4a10853'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '9864d8e8-0aff-486e-8b84-7a8d20c017d4') - }], - 'id': '48fd97b1-e166-4aff-906f-8096a48a7cb1' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.added_flows, [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:%d' % self.int_patch, - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': self.int_patch, - 'priority': 10, - 'table': 30 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 6, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:1', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:42' - ), - 'dl_dst': '00:01:02:03:06:08', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:67:cb,' - 'set_field:51->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65790, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 25, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:60' - ), - 'dl_dst': '00:01:02:03:06:09', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 50, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:5' - ), - 'dl_dst': '00:01:02:03:06:11', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 8, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:4' - ), - 'dl_dst': '00:01:02:03:06:13', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:74:c1,' - 'set_field:51->tun_id,output:[],' - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:4f:6e,' - 'set_field:51->tun_id,output:[],' - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:d5:66,' - 'set_field:51->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - } - } - ) - - def test_update_flow_rules_multi_flow_classifiers(self): - self.port_mapping = { - '54abe601-6685-4c38-9b9d-0d8381a43d56': { - 'port_name': 'port1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - 'c2de00c2-bd91-4f60-8a7d-5a3ea8f65e77': { - 'port_name': 'port2', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - '460a5875-b0c6-408e-ada4-0ef01d39bcff': { - 'port_name': 'port3', - 'ofport': 60, - 'vif_mac': '00:01:02:03:06:09' - }, - 'b2b8a556-593b-4695-8812-cdd33a314867': { - 'port_name': 'port4', - 'ofport': 25, - 'vif_mac': '00:01:02:03:06:10' - }, - '2656a373-a985-4940-90d1-cfe172951e0c': { - 'port_name': 'port5', - 'ofport': 5, - 'vif_mac': '00:01:02:03:06:11' - }, - 'a979a847-3014-43ea-b37d-5a3775a173c7': { - 'port_name': 'port6', - 'ofport': 50, - 'vif_mac': '00:01:02:03:06:12' - } - } - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'2656a373-a985-4940-90d1-cfe172951e0c', - 'weight': 1, - 'mac_address': u'12:34:56:78:5f:ea' - }], - 'del_fcs': [], - 'segment_id': 58, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:b9:09', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'src_node', - 'egress': u'54abe601-6685-4c38-9b9d-0d8381a43d56', - 'next_group_id': 1, - 'host_id': u'test1', - 'nsp': 256, - 'portchain_id': u'3eefdf29-ea8f-4794-a36f-5e60ec7fe208', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '460a5875-b0c6-408e-ada4-0ef01d39bcff'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '54abe601-6685-4c38-9b9d-0d8381a43d56') - }], - 'id': 'd2e675d3-739e-4451-95d5-a15e23c6eaac' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'2656a373-a985-4940-90d1-cfe172951e0c', - 'weight': 1, - 'mac_address': u'12:34:56:78:5f:ea' - }], - 'del_fcs': [], - 'segment_id': 58, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:4d:d1', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'src_node', - 'egress': u'c2de00c2-bd91-4f60-8a7d-5a3ea8f65e77', - 'next_group_id': 1, - 'host_id': u'test3', - 'nsp': 256, - 'portchain_id': u'3eefdf29-ea8f-4794-a36f-5e60ec7fe208', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - 'b2b8a556-593b-4695-8812-cdd33a314867'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - 'c2de00c2-bd91-4f60-8a7d-5a3ea8f65e77') - }], - 'id': 'd2e675d3-739e-4451-95d5-a15e23c6eaac' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': u'460a5875-b0c6-408e-ada4-0ef01d39bcff', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 58, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:fc:b8', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': u'test2', - 'nsp': 256, - 'portchain_id': u'3eefdf29-ea8f-4794-a36f-5e60ec7fe208', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '460a5875-b0c6-408e-ada4-0ef01d39bcff'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '54abe601-6685-4c38-9b9d-0d8381a43d56') - }], - 'id': '029823ae-8524-4e1c-8f5b-4ee7ec55f1bd' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': u'b2b8a556-593b-4695-8812-cdd33a314867', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 58, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:7b:15', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': u'test4', - 'nsp': 256, - 'portchain_id': u'3eefdf29-ea8f-4794-a36f-5e60ec7fe208', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - 'b2b8a556-593b-4695-8812-cdd33a314867'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - 'c2de00c2-bd91-4f60-8a7d-5a3ea8f65e77') - }], - 'id': '029823ae-8524-4e1c-8f5b-4ee7ec55f1bd' - } - ) - self.agent.update_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': u'2656a373-a985-4940-90d1-cfe172951e0c', - 'next_hops': [{ - 'local_endpoint': u'10.0.0.2', - 'ingress': u'460a5875-b0c6-408e-ada4-0ef01d39bcff', - 'weight': 1, - 'mac_address': u'12:34:56:78:fc:b8' - }, { - 'local_endpoint': u'10.0.0.2', - 'ingress': u'b2b8a556-593b-4695-8812-cdd33a314867', - 'weight': 1, - 'mac_address': u'12:34:56:78:7b:15' - }], - 'del_fcs': [], - 'segment_id': 58, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:5f:ea', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'a979a847-3014-43ea-b37d-5a3775a173c7', - 'next_group_id': None, - 'host_id': u'test5', - 'nsp': 256, - 'portchain_id': u'3eefdf29-ea8f-4794-a36f-5e60ec7fe208', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - '460a5875-b0c6-408e-ada4-0ef01d39bcff'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - '54abe601-6685-4c38-9b9d-0d8381a43d56') - }, { - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'logical_destination_port': ( - 'b2b8a556-593b-4695-8812-cdd33a314867'), - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'destination_port_range_min': None, - 'ethertype': u'IPv4', - 'destination_port_range_max': None, - 'logical_source_port': ( - 'c2de00c2-bd91-4f60-8a7d-5a3ea8f65e77') - }], - 'id': '983cfa51-f9e6-4e36-8f6c-0c84df915cd1' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.added_flows, [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:%d' % self.int_patch, - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': self.int_patch, - 'priority': 10, - 'table': 30 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 6, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:1', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 42, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:60' - ), - 'dl_dst': '00:01:02:03:06:09', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:25' - ), - 'dl_dst': '00:01:02:03:06:10', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:fc:b8,' - 'set_field:58->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65790, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:%d' % self.tun_patch - ), - 'dl_type': 2048, - 'in_port': 50, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:7b:15,' - 'set_field:58->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65790, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:5' - ), - 'dl_dst': '00:01:02:03:06:11', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:5f:ea,' - 'set_field:58->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - } - } - ) - - def test_delete_flow_rules_port_pair(self): - self.port_mapping = { - 'dd7374b9-a6ac-4a66-a4a6-7d3dee2a1579': { - 'port_name': 'src_port', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '2f1d2140-42ce-4979-9542-7ef25796e536': { - 'port_name': 'dst_port', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - } - } - self.agent.delete_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': u'dd7374b9-a6ac-4a66-a4a6-7d3dee2a1579', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 75, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:fd:b2', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'sf_node', - 'egress': u'2f1d2140-42ce-4979-9542-7ef25796e536', - 'next_group_id': None, - 'host_id': u'test1', - 'nsp': 256, - 'portchain_id': u'84c1411f-7a94-4b4f-9a8b-ad9607c67c76', - 'add_fcs': [], - 'id': '611bdc42-12b3-4639-8faf-83da4e6403f7' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.deleted_flows, [{ - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': '65791', - 'table': 5 - }, { - 'dl_type': 34887, - 'mpls_label': '65790', - 'table': 31 - }] - ) - self.assertEqual( - self.deleted_groups, [ - ] - ) - - def test_delete_flow_rules_flow_classifiers(self): - self.port_mapping = { - 'e1229670-2a07-450d-bdc9-34e71c301206': { - 'port_name': 'src_port', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '9bedd01e-c216-4dfd-b48e-fbd5c8212ba4': { - 'port_name': 'dst_port', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - } - } - - self.agent.delete_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': None, - 'add_fcs': [], - 'segment_id': 43, - 'group_refcnt': 1, - 'mac_address': u'12:34:56:78:72:05', - 'network_type': u'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'src_node', - 'egress': u'9bedd01e-c216-4dfd-b48e-fbd5c8212ba4', - 'next_group_id': 1, - 'host_id': u'test1', - 'nsp': 256, - 'portchain_id': u'8cba323e-5e67-4df0-a4b0-7e1ef486a656', - 'del_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': u'10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - 'e1229670-2a07-450d-bdc9-34e71c301206'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': u'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '9bedd01e-c216-4dfd-b48e-fbd5c8212ba4') - }], - 'id': '611bdc42-12b3-4639-8faf-83da4e6403f7' - } - ) - self.agent.delete_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': 'e1229670-2a07-450d-bdc9-34e71c301206', - 'next_hops': None, - 'add_fcs': [], - 'segment_id': 43, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:c5:f3', - 'network_type': 'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': u'test2', - 'nsp': 256, - 'portchain_id': '8cba323e-5e67-4df0-a4b0-7e1ef486a656', - 'del_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': u'10.200.0.0/16', - 'protocol': 'tcp', - 'logical_destination_port': ( - 'e1229670-2a07-450d-bdc9-34e71c301206'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': 'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '9bedd01e-c216-4dfd-b48e-fbd5c8212ba4') - }], - 'id': '611bdc42-12b3-4639-8faf-83da4e6403f8' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.deleted_flows, [{ - 'dl_type': 2048, - 'in_port': 42, - 'nw_dst': u'10.200.0.0/16', - 'nw_proto': 6, - 'nw_src': u'10.100.0.0/16', - 'table': 0, - 'tp_dst': '0x12c/0xffff', - 'tp_src': '0x64/0xffff' - }, { - 'dl_type': 34887, - 'mpls_label': '65791', - 'table': 31 - }, { - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': '65790', - 'table': 5 - }] - ) - self.assertEqual( - self.deleted_groups, [1] - ) - - def test_delete_flow_rules_flow_classifiers_port_pairs(self): - self.port_mapping = { - '8768d2b3-746d-4868-ae0e-e81861c2b4e6': { - 'port_name': 'port1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '29e38fb2-a643-43b1-baa8-a86596461cd5': { - 'port_name': 'port2', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - '82a575e0-6a6e-46ba-a5fc-692407839a85': { - 'port_name': 'port3', - 'ofport': 60, - 'vif_mac': '00:01:02:03:06:09' - }, - '93466f5d-252e-4552-afc6-5fb3f6019f76': { - 'port_name': 'port4', - 'ofport': 25, - 'vif_mac': '00:01:02:03:06:10' - } - } - self.agent.delete_flow_rules( - self.context, flowrule_entries={ - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.2', - 'ingress': '8768d2b3-746d-4868-ae0e-e81861c2b4e6', - 'weight': 1, - 'mac_address': '12:34:56:78:cf:23' - }], - 'add_fcs': [], - 'segment_id': 33, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:ed:01', - 'network_type': 'gre', - 'local_endpoint': u'10.0.0.2', - 'node_type': 'src_node', - 'egress': '29e38fb2-a643-43b1-baa8-a86596461cd5', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': 'b9570dc9-822b-41fc-a27c-d915a21a3fe8', - 'del_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': u'10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - '82a575e0-6a6e-46ba-a5fc-692407839a85'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': '10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': 'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '29e38fb2-a643-43b1-baa8-a86596461cd5') - }], - 'id': '73e97aad-8c0f-44e3-bee0-c0a641b00b66' - } - ) - self.agent.delete_flow_rules( - self.context, flowrule_entries={ - 'nsi': 253, - 'ingress': '82a575e0-6a6e-46ba-a5fc-692407839a85', - 'next_hops': None, - 'add_fcs': [], - 'segment_id': 33, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:a6:84', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': 'b9570dc9-822b-41fc-a27c-d915a21a3fe8', - 'del_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': '10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - '82a575e0-6a6e-46ba-a5fc-692407839a85'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': u'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '29e38fb2-a643-43b1-baa8-a86596461cd5') - }], - 'id': 'fa385d84-7d78-44e7-aa8d-7b4a279a14d7' - } - ) - self.agent.delete_flow_rules( - self.context, flowrule_entries={ - 'nsi': 254, - 'ingress': '8768d2b3-746d-4868-ae0e-e81861c2b4e6', - 'next_hops': [{ - 'local_endpoint': '10.0.0.2', - 'ingress': '82a575e0-6a6e-46ba-a5fc-692407839a85', - 'weight': 1, - 'mac_address': '12:34:56:78:a6:84' - }], - 'add_fcs': [], - 'segment_id': 33, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:cf:23', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'sf_node', - 'egress': '93466f5d-252e-4552-afc6-5fb3f6019f76', - 'next_group_id': None, - 'host_id': 'test3', - 'nsp': 256, - 'portchain_id': 'b9570dc9-822b-41fc-a27c-d915a21a3fe8', - 'del_fcs': [{ - 'source_port_range_min': 100, - 'destination_ip_prefix': '10.200.0.0/16', - 'protocol': u'tcp', - 'logical_destination_port': ( - '82a575e0-6a6e-46ba-a5fc-692407839a85'), - 'l7_parameters': {}, - 'source_port_range_max': 100, - 'source_ip_prefix': u'10.100.0.0/16', - 'destination_port_range_min': 300, - 'ethertype': u'IPv4', - 'destination_port_range_max': 300, - 'logical_source_port': ( - '29e38fb2-a643-43b1-baa8-a86596461cd5') - }], - 'id': '07cc65a8-e99b-4175-a2f1-69b87eb8090a' - } - ) - self.assertEqual( - self.executed_cmds, [ - ] - ) - self.assertEqual( - self.deleted_flows, [{ - 'dl_type': 2048, - 'in_port': 42, - 'nw_dst': u'10.200.0.0/16', - 'nw_proto': 6, - 'nw_src': '10.100.0.0/16', - 'table': 0, - 'tp_dst': '0x12c/0xffff', - 'tp_src': '0x64/0xffff' - }, { - 'dl_type': 34887, - 'mpls_label': '65791', - 'table': 31 - }, { - 'dl_dst': '00:01:02:03:06:09', - 'dl_type': 34887, - 'mpls_label': '65790', - 'table': 5 - }, { - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': '65791', - 'table': 5 - }, { - 'dl_type': 2048, - 'in_port': 25, - 'nw_dst': '10.200.0.0/16', - 'nw_proto': 6, - 'nw_src': u'10.100.0.0/16', - 'table': 0, - 'tp_dst': '0x12c/0xffff', - 'tp_src': '0x64/0xffff' - }, { - 'dl_type': 34887, - 'mpls_label': '65790', - 'table': 31 - }] - ) - self.assertEqual( - self.deleted_groups, [1] - ) - - def test_init_agent_empty_flowrules(self): - self.node_flowrules = [] - self.init_agent() - self.assertItemsEqual( - self.added_flows, - [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:1', - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': 1, - 'priority': 10, - 'table': 30 - }] - ) - self.assertEqual(self.group_mapping, {}) - - def test_init_agent_portchain_portpairs(self): - self.port_mapping = { - '4f72c5fc-37e9-4e6f-8cd8-e8166c4b45c4': { - 'port_name': 'ingress', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '57f35c35-dceb-4934-9a78-b40a0a3e16b3': { - 'port_name': 'egress', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - } - } - self.node_flowrules = [{ - 'nsi': 254, - 'ingress': '4f72c5fc-37e9-4e6f-8cd8-e8166c4b45c4', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 34, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:2d:f4', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'sf_node', - 'egress': '57f35c35-dceb-4934-9a78-b40a0a3e16b3', - 'next_group_id': None, - 'host_id': u'test2', - 'nsp': 256, - 'portchain_id': '0f604e43-c941-4f42-a96c-8bd027e5507d', - 'add_fcs': [], - 'id': 'b6ebb2c3-4e9c-4146-8a74-f3985173dc44' - }] - self.init_agent() - for port_id in self.port_mapping: - self.agent.sfc_treat_devices_added_updated(port_id) - self.assertItemsEqual( - self.added_flows, - [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:1', - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': 1, - 'priority': 10, - 'table': 30 - }, { - 'actions': 'pop_mpls:0x0800,output:6', - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': agent.SF_SELECTOR - }] - ) - self.assertEqual(self.group_mapping, {}) - - def test_init_agent_portchain_flowclassifiers(self): - self.port_mapping = { - '5aa33c52-535a-48eb-a77c-e02329bb9eb7': { - 'port_name': 'src_port', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '079d214c-1aea-439d-bf3c-dad03db47dcb': { - 'port_name': 'dst_port', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - } - } - self.node_flowrules = [{ - 'nsi': 253, - 'ingress': '5aa33c52-535a-48eb-a77c-e02329bb9eb7', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 43, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:ac:22', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.3', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': 'd66efb47-f080-41da-8499-c6e89327ecc0', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '5aa33c52-535a-48eb-a77c-e02329bb9eb7'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '079d214c-1aea-439d-bf3c-dad03db47dcb' - }], - 'id': '9d8ec269-874a-42b2-825f-d25858341ec2' - }, { - 'nsi': 255, - 'ingress': None, - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 43, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:e3:b3', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'src_node', - 'egress': '079d214c-1aea-439d-bf3c-dad03db47dcb', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': 'd66efb47-f080-41da-8499-c6e89327ecc0', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '5aa33c52-535a-48eb-a77c-e02329bb9eb7'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '079d214c-1aea-439d-bf3c-dad03db47dcb' - }], - 'id': u'361811ed-2902-4d35-9fe4-a3a2b062ef37' - }] - self.init_agent() - for port_id in self.port_mapping: - self.agent.sfc_treat_devices_added_updated(port_id) - self.assertItemsEqual( - self.added_flows, - [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:1', - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': 1, - 'priority': 10, - 'table': 30 - }, { - 'actions': 'pop_mpls:0x0800,output:6', - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }] - ) - self.assertEqual(self.group_mapping, {}) - - def test_init_agent_portchain_flow_classifiers_port_pairs(self): - self.port_mapping = { - '2881f577-3828-40f2-855d-2f86d63a4733': { - 'port_name': 'dst_port', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '5546e281-319b-4bdd-95c9-37fe4244aeb3': { - 'port_name': 'ingress', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - 'c45ccd73-46ad-4d91-b44d-68c15a822521': { - 'port_name': 'egress', - 'ofport': 43, - 'vif_mac': '00:01:02:03:06:09' - }, - 'd2ebbafb-500e-4926-9751-de73906a1e00': { - 'port_name': 'src_port', - 'ofport': 44, - 'vif_mac': '00:01:02:03:06:10' - } - } - self.node_flowrules = [{ - 'nsi': 253, - 'ingress': '2881f577-3828-40f2-855d-2f86d63a4733', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 67, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:17:0c', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.3', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': 'cddb174c-9e50-4411-b844-41ecb9caf4c4', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': u'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2881f577-3828-40f2-855d-2f86d63a4733'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': 'd2ebbafb-500e-4926-9751-de73906a1e00' - }], - 'id': '752ca419-6729-461f-993f-fbd44bbd0edb' - }, { - 'nsi': 254, - 'ingress': '5546e281-319b-4bdd-95c9-37fe4244aeb3', - 'next_hops': [{ - 'local_endpoint': '10.0.0.3', - 'ingress': '2881f577-3828-40f2-855d-2f86d63a4733', - 'weight': 1, - 'mac_address': '12:34:56:78:17:0c' - }], - 'del_fcs': [], - 'segment_id': 67, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:ca:de', - 'network_type': u'gre', - 'local_endpoint': '10.0.0.4', - 'node_type': 'sf_node', - 'egress': 'c45ccd73-46ad-4d91-b44d-68c15a822521', - 'next_group_id': None, - 'host_id': 'test4', - 'nsp': 256, - 'portchain_id': 'cddb174c-9e50-4411-b844-41ecb9caf4c4', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2881f577-3828-40f2-855d-2f86d63a4733'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': 'd2ebbafb-500e-4926-9751-de73906a1e00' - }], - 'id': 'f70d81ec-1b7c-4ab4-9cf3-da5375ad47e9' - }, { - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.4', - 'ingress': '5546e281-319b-4bdd-95c9-37fe4244aeb3', - 'weight': 1, - 'mac_address': '12:34:56:78:ca:de' - }], - 'del_fcs': [], - 'segment_id': 67, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:8c:68', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'src_node', - 'egress': 'd2ebbafb-500e-4926-9751-de73906a1e00', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': 'cddb174c-9e50-4411-b844-41ecb9caf4c4', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2881f577-3828-40f2-855d-2f86d63a4733'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': 'd2ebbafb-500e-4926-9751-de73906a1e00' - }], - 'id': 'f52624f0-81d9-4041-81cf-dfe151d3a949' - }] - self.init_agent() - for port_id in self.port_mapping: - self.agent.sfc_treat_devices_added_updated(port_id) - self.assertItemsEqual( - self.added_flows, [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:1', - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': 1, - 'priority': 10, - 'table': 30 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,' - 'output:2' - ), - 'dl_type': 2048, - 'in_port': 44, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:1', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:17:0c,' - 'set_field:67->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65790, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:2' - ), - 'dl_type': 2048, - 'in_port': 43, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'pop_mpls:0x0800,output:42', - 'dl_dst': '00:01:02:03:06:08', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }, { - 'actions': 'pop_mpls:0x0800,output:6', - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:ca:de,' - 'set_field:67->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - } - } - ) - - def test_init_agent_portchain_multi_port_groups_port_pairs(self): - self.port_mapping = { - '495d5bcf-f8ef-47d7-995a-5a8ef2e6d1ea': { - 'port_name': 'ingress1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '0dd212fb-1e0f-4b1a-abc2-a3a39bbab3ef': { - 'port_name': 'egress1', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - '6d7aa494-7796-46ea-9cfe-52d2b0f84217': { - 'port_name': 'src_port', - 'ofport': 43, - 'vif_mac': '00:01:02:03:06:09' - }, - '028c5816-7d4b-453e-8ec2-f3a084ae992f': { - 'port_name': 'ingress2', - 'ofport': 44, - 'vif_mac': '00:01:02:03:06:10' - }, - '3e4e8d33-334b-4c67-8e04-143eeb6f8351': { - 'port_name': 'egress2', - 'ofport': 45, - 'vif_mac': '00:01:02:03:06:11' - }, - '73d1dbc7-ba46-4b16-85a0-73b106a96fa1': { - 'port_name': 'dst_port', - 'ofport': 46, - 'vif_mac': '00:01:02:03:06:12' - }, - '1778085d-9f81-4e1e-9748-0bafece63344': { - 'port_name': 'ingress3', - 'ofport': 47, - 'vif_mac': '00:01:02:03:06:13' - }, - 'a47cbe65-ea3f-4faa-af27-8212a121c91f': { - 'port_name': 'egress3', - 'ofport': 48, - 'vif_mac': '00:01:02:03:06:14' - } - } - self.node_flowrules = [{ - 'nsi': 254, - 'ingress': '495d5bcf-f8ef-47d7-995a-5a8ef2e6d1ea', - 'next_hops': [{ - 'local_endpoint': u'10.0.0.6', - 'ingress': '73d1dbc7-ba46-4b16-85a0-73b106a96fa1', - 'weight': 1, - 'mac_address': '12:34:56:78:51:cc' - }], - 'del_fcs': [], - 'segment_id': 7, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:1d:84', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.4', - 'node_type': 'sf_node', - 'egress': '0dd212fb-1e0f-4b1a-abc2-a3a39bbab3ef', - 'next_group_id': 2, - 'host_id': 'test3', - 'nsp': 256, - 'portchain_id': '0aa6b9fe-6b5e-4b72-91aa-45bce6587ca7', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'a47cbe65-ea3f-4faa-af27-8212a121c91f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '6d7aa494-7796-46ea-9cfe-52d2b0f84217' - }], - 'id': u'1fe85cf2-41fb-4b30-80de-4ae35d3c2b1c' - }, { - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.4', - 'ingress': '495d5bcf-f8ef-47d7-995a-5a8ef2e6d1ea', - 'weight': 1, - 'mac_address': '12:34:56:78:1d:84' - }], - 'del_fcs': [], - 'segment_id': 7, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:45:d7', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'src_node', - 'egress': '6d7aa494-7796-46ea-9cfe-52d2b0f84217', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': '0aa6b9fe-6b5e-4b72-91aa-45bce6587ca7', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'a47cbe65-ea3f-4faa-af27-8212a121c91f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '6d7aa494-7796-46ea-9cfe-52d2b0f84217' - }], - 'id': '3c4b700b-e993-4378-b41a-95f609b3c799' - }, { - 'nsi': 252, - 'ingress': '028c5816-7d4b-453e-8ec2-f3a084ae992f', - 'next_hops': [{ - 'local_endpoint': '10.0.0.3', - 'ingress': 'a47cbe65-ea3f-4faa-af27-8212a121c91f', - 'weight': 1, - 'mac_address': '12:34:56:78:54:76' - }], - 'del_fcs': [], - 'segment_id': 7, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:47:34', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.8', - 'node_type': 'sf_node', - 'egress': '3e4e8d33-334b-4c67-8e04-143eeb6f8351', - 'next_group_id': None, - 'host_id': 'test8', - 'nsp': 256, - 'portchain_id': '0aa6b9fe-6b5e-4b72-91aa-45bce6587ca7', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'a47cbe65-ea3f-4faa-af27-8212a121c91f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': u'6d7aa494-7796-46ea-9cfe-52d2b0f84217' - }], - 'id': '05574d93-104e-425f-8a30-640721f2c749' - }, { - 'nsi': 253, - 'ingress': '73d1dbc7-ba46-4b16-85a0-73b106a96fa1', - 'next_hops': [{ - 'local_endpoint': '10.0.0.8', - 'ingress': '028c5816-7d4b-453e-8ec2-f3a084ae992f', - 'weight': 1, - 'mac_address': '12:34:56:78:47:34' - }], - 'del_fcs': [], - 'segment_id': 7, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:51:cc', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.6', - 'node_type': 'sf_node', - 'egress': '1778085d-9f81-4e1e-9748-0bafece63344', - 'next_group_id': 3, - 'host_id': 'test5', - 'nsp': 256, - 'portchain_id': '0aa6b9fe-6b5e-4b72-91aa-45bce6587ca7', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'a47cbe65-ea3f-4faa-af27-8212a121c91f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '6d7aa494-7796-46ea-9cfe-52d2b0f84217' - }], - 'id': u'5038a916-93de-4734-a830-d88c9d65566c' - }, { - 'nsi': 251, - 'ingress': 'a47cbe65-ea3f-4faa-af27-8212a121c91f', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 7, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:54:76', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.3', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': '0aa6b9fe-6b5e-4b72-91aa-45bce6587ca7', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'a47cbe65-ea3f-4faa-af27-8212a121c91f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '6d7aa494-7796-46ea-9cfe-52d2b0f84217' - }], - 'id': '42b8abe6-5bfa-47c5-a992-771e333dae52' - }] - self.init_agent() - for port_id in self.port_mapping: - self.agent.sfc_treat_devices_added_updated(port_id) - self.assertItemsEqual( - self.added_flows, [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:1', - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': 1, - 'priority': 10, - 'table': 30 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65789,' - 'set_mpls_ttl:253,output:2' - ), - 'dl_type': 2048, - 'in_port': 47, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:3', - 'dl_type': 34887, - 'mpls_label': 65789, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'pop_mpls:0x0800,' - 'output:46' - ), - 'dl_dst': '00:01:02:03:06:12', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:54:76,' - 'set_field:7->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65788, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65788,' - 'set_mpls_ttl:252,output:2' - ), - 'dl_type': 2048, - 'in_port': 45, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'pop_mpls:0x0800,output:44', - 'dl_dst': '00:01:02:03:06:10', - 'dl_type': 34887, - 'mpls_label': 65789, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:2' - ), - 'dl_type': 2048, - 'in_port': 43, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:1', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 0, - 'table': 31 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:2' - ), - 'dl_type': 2048, - 'in_port': 42, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:2', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 0, - 'table': 31 - }, { - 'actions': 'pop_mpls:0x0800,output:6', - 'dl_dst': '00:01:02:03:05:07', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }, { - 'actions': 'pop_mpls:0x0800,output:48', - 'dl_dst': '00:01:02:03:06:14', - 'dl_type': 34887, - 'mpls_label': 65788, - 'priority': 1, - 'table': 5 - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:1d:84,' - 'set_field:7->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - }, - 2: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:51:cc,' - 'set_field:7->tun_id,output:[]' - ), - 'group_id': 2, - 'type': 'select' - }, - 3: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:47:34,' - 'set_field:7->tun_id,output:[]' - ), - 'group_id': 3, - 'type': 'select' - } - } - ) - - def test_init_agent_portchain_port_group_multi_port_pairs(self): - self.port_mapping = { - '8849af69-117d-4db9-83fa-85329b0efbd6': { - 'port_name': 'ingress1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '51f58f0f-6870-4e75-9fd1-13cf3ce29b3e': { - 'port_name': 'egress1', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - 'a57a8160-a202-477b-aca1-e7c006bc93a2': { - 'port_name': 'src_port', - 'ofport': 43, - 'vif_mac': '00:01:02:03:06:09' - }, - '23d02749-7f2b-456d-b9f1-7869300375d4': { - 'port_name': 'ingress2', - 'ofport': 44, - 'vif_mac': '00:01:02:03:06:10' - }, - 'c5dacf1c-f84a-43e0-8873-b2cba77970af': { - 'port_name': 'egress2', - 'ofport': 45, - 'vif_mac': '00:01:02:03:06:11' - }, - '2b17abfa-7afb-4e83-8e15-ad21a6044bb7': { - 'port_name': 'dst_port', - 'ofport': 46, - 'vif_mac': '00:01:02:03:06:12' - }, - 'b299c792-28c8-4f6a-84a0-589163a9b1d4': { - 'port_name': 'ingress3', - 'ofport': 47, - 'vif_mac': '00:01:02:03:06:13' - }, - '60d47d04-42c0-4478-9136-6247fd5d058d': { - 'port_name': 'egress3', - 'ofport': 48, - 'vif_mac': '00:01:02:03:06:14' - } - } - self.node_flowrules = [{ - 'nsi': 254, - 'ingress': '8849af69-117d-4db9-83fa-85329b0efbd6', - 'next_hops': [{ - 'local_endpoint': '10.0.0.3', - 'ingress': '2b17abfa-7afb-4e83-8e15-ad21a6044bb7', - 'weight': 1, - 'mac_address': '12:34:56:78:68:3a' - }], - 'del_fcs': [], - 'segment_id': 68, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:fe:38', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.6', - 'node_type': 'sf_node', - 'egress': '51f58f0f-6870-4e75-9fd1-13cf3ce29b3e', - 'next_group_id': None, - 'host_id': 'test6', - 'nsp': 256, - 'portchain_id': '10f6a764-6963-4b8e-9ae4-a1e5e805915e', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b17abfa-7afb-4e83-8e15-ad21a6044bb7'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': 'a57a8160-a202-477b-aca1-e7c006bc93a2' - }], - 'id': u'1409e7b8-ed6f-41ae-ba6b-8ef96bbb8da9' - }, { - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.4', - 'ingress': 'b299c792-28c8-4f6a-84a0-589163a9b1d4', - 'weight': 1, - 'mac_address': '12:34:56:78:58:ee' - }, { - 'local_endpoint': '10.0.0.6', - 'ingress': '8849af69-117d-4db9-83fa-85329b0efbd6', - 'weight': 1, - 'mac_address': '12:34:56:78:fe:38' - }, { - 'local_endpoint': '10.0.0.8', - 'ingress': '23d02749-7f2b-456d-b9f1-7869300375d4', - 'weight': 1, - 'mac_address': '12:34:56:78:32:30' - }], - 'del_fcs': [], - 'segment_id': 68, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:e0:a9', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'src_node', - 'egress': 'a57a8160-a202-477b-aca1-e7c006bc93a2', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': '10f6a764-6963-4b8e-9ae4-a1e5e805915e', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b17abfa-7afb-4e83-8e15-ad21a6044bb7'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': ( - 'a57a8160-a202-477b-aca1-e7c006bc93a2') - }], - 'id': '6c686bd6-a064-4650-ace7-0bd34fa4238a' - }, { - 'nsi': 254, - 'ingress': '23d02749-7f2b-456d-b9f1-7869300375d4', - 'next_hops': [{ - 'local_endpoint': '10.0.0.3', - 'ingress': '2b17abfa-7afb-4e83-8e15-ad21a6044bb7', - 'weight': 1, - 'mac_address': '12:34:56:78:68:3a' - }], - 'del_fcs': [], - 'segment_id': 68, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:32:30', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.8', - 'node_type': 'sf_node', - 'egress': 'c5dacf1c-f84a-43e0-8873-b2cba77970af', - 'next_group_id': None, - 'host_id': u'test8', - 'nsp': 256, - 'portchain_id': '10f6a764-6963-4b8e-9ae4-a1e5e805915e', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b17abfa-7afb-4e83-8e15-ad21a6044bb7'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': ( - 'a57a8160-a202-477b-aca1-e7c006bc93a2') - }], - 'id': u'1409e7b8-ed6f-41ae-ba6b-8ef96bbb8da9' - }, { - 'nsi': 253, - 'ingress': '2b17abfa-7afb-4e83-8e15-ad21a6044bb7', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 68, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:68:3a', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.3', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': '10f6a764-6963-4b8e-9ae4-a1e5e805915e', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b17abfa-7afb-4e83-8e15-ad21a6044bb7'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': ( - 'a57a8160-a202-477b-aca1-e7c006bc93a2') - }], - 'id': '12a279c1-cf81-4c1b-bac3-e9690465aeaf' - }, { - 'nsi': 254, - 'ingress': 'b299c792-28c8-4f6a-84a0-589163a9b1d4', - 'next_hops': [{ - 'local_endpoint': '10.0.0.3', - 'ingress': '2b17abfa-7afb-4e83-8e15-ad21a6044bb7', - 'weight': 1, - 'mac_address': '12:34:56:78:68:3a' - }], - 'del_fcs': [], - 'segment_id': 68, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:58:ee', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.4', - 'node_type': 'sf_node', - 'egress': '60d47d04-42c0-4478-9136-6247fd5d058d', - 'next_group_id': None, - 'host_id': 'test4', - 'nsp': 256, - 'portchain_id': '10f6a764-6963-4b8e-9ae4-a1e5e805915e', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b17abfa-7afb-4e83-8e15-ad21a6044bb7'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': 'a57a8160-a202-477b-aca1-e7c006bc93a2' - }], - 'id': '1409e7b8-ed6f-41ae-ba6b-8ef96bbb8da9' - }] - self.init_agent() - for port_id in self.port_mapping: - self.agent.sfc_treat_devices_added_updated(port_id) - self.assertItemsEqual( - self.added_flows, [{ - 'priority': 10, - 'table': 0, - 'dl_type': 34887, - 'actions': 'resubmit(,5)' - }, { - 'dl_type': 34887, - 'priority': 10, - 'actions': 'resubmit(,30)' - }, { - 'priority': 0, - 'table': 30, - 'actions': 'output:1' - }, { - 'priority': 10, - 'table': 30, - 'actions': 'resubmit(,31)', - 'in_port': 1 - }, { - 'dl_type': 34887, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'actions': ( - 'mod_dl_dst:12:34:56:78:68:3a,' - 'set_field:68->tun_id,output:[]' - ), - 'priority': 0, - 'mpls_label': 65790, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0', - 'table': 31, - 'nw_src': '0.0.0.0/0.0.0.0' - }, { - 'dl_type': 2048, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:2' - ), - 'priority': 10, - 'tp_dst': '0/0x0', - 'table': 0, - 'tp_src': '0/0x0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'in_port': 42 - }, { - 'dl_type': 34887, - 'actions': 'pop_mpls:0x0800,output:6', - 'priority': 1, - 'mpls_label': 65791, - 'table': 5, - 'dl_dst': '00:01:02:03:05:07' - }, { - 'dl_type': 2048, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:2' - ), - 'priority': 10, - 'tp_dst': '0/0x0', - 'table': 0, - 'tp_src': '0/0x0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'in_port': 45 - }, { - 'dl_type': 34887, - 'actions': 'pop_mpls:0x0800,output:44', - 'priority': 1, - 'mpls_label': 65791, - 'table': 5, - 'dl_dst': '00:01:02:03:06:10' - }, { - 'dl_type': 2048, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:2' - ), - 'priority': 10, - 'tp_dst': '0/0x0', - 'table': 0, - 'tp_src': '0/0x0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'in_port': 48 - }, { - 'dl_type': 34887, - 'actions': 'pop_mpls:0x0800,output:47', - 'priority': 1, - 'mpls_label': 65791, - 'table': 5, - 'dl_dst': '00:01:02:03:06:13' - }, { - 'dl_type': 2048, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:2' - ), - 'priority': 10, - 'tp_dst': '0/0x0', - 'table': 0, - 'tp_src': '0/0x0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'in_port': 43 - }, { - 'priority': 0, - 'table': 31, - 'dl_type': 34887, - 'mpls_label': 65791, - 'actions': 'group:1' - }, { - 'dl_type': 34887, - 'actions': 'pop_mpls:0x0800,output:46', - 'priority': 1, - 'mpls_label': 65790, - 'table': 5, - 'dl_dst': '00:01:02:03:06:12' - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:58:ee,' - 'set_field:68->tun_id,output:[],' - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:fe:38,' - 'set_field:68->tun_id,output:[],' - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:32:30,' - 'set_field:68->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - } - } - ) - - def test_init_agent_portchain_multi_flow_classifiers_port_pairs(self): - self.port_mapping = { - '7b718ad7-c2cc-4de0-9ac0-d5f4b6e975aa': { - 'port_name': 'src_port1', - 'ofport': 6, - 'vif_mac': '00:01:02:03:05:07' - }, - '9ac01d29-797a-4904-97a0-eecc7661b2ad': { - 'port_name': 'ingress', - 'ofport': 42, - 'vif_mac': '00:01:02:03:06:08' - }, - '02ebda8f-44e5-41ee-8d80-ec47b3c2732e': { - 'port_name': 'egress', - 'ofport': 43, - 'vif_mac': '00:01:02:03:06:09' - }, - '32971131-e44c-4aad-85f9-7d9f10d07393': { - 'port_name': 'src_port2', - 'ofport': 44, - 'vif_mac': '00:01:02:03:06:10' - }, - 'b7c69625-9cde-48dd-8858-5d773b002e73': { - 'port_name': 'dst_port1', - 'ofport': 45, - 'vif_mac': '00:01:02:03:06:11' - }, - '2b7e8e42-b35d-4d49-8397-62088efe144f': { - 'port_name': 'dst_port2', - 'ofport': 46, - 'vif_mac': '00:01:02:03:06:12' - } - } - self.node_flowrules = [{ - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.6', - 'ingress': '9ac01d29-797a-4904-97a0-eecc7661b2ad', - 'weight': 1, - 'mac_address': '12:34:56:78:52:39' - }], - 'del_fcs': [], - 'segment_id': 82, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:65:d7', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.4', - 'node_type': 'src_node', - 'egress': '7b718ad7-c2cc-4de0-9ac0-d5f4b6e975aa', - 'next_group_id': 1, - 'host_id': 'test3', - 'nsp': 256, - 'portchain_id': 'd92114e8-56df-4bd7-9cf2-fce5ac01c94f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b7e8e42-b35d-4d49-8397-62088efe144f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '7b718ad7-c2cc-4de0-9ac0-d5f4b6e975aa' - }], - 'id': u'44c469bf-6c48-4f8f-bb4f-de87b44b02b6' - }, { - 'nsi': 254, - 'ingress': '9ac01d29-797a-4904-97a0-eecc7661b2ad', - 'next_hops': [{ - 'local_endpoint': '10.0.0.3', - 'ingress': 'b7c69625-9cde-48dd-8858-5d773b002e73', - 'weight': 1, - 'mac_address': '12:34:56:78:36:e9' - }, { - 'local_endpoint': '10.0.0.5', - 'ingress': '2b7e8e42-b35d-4d49-8397-62088efe144f', - 'weight': 1, - 'mac_address': '12:34:56:78:51:9a' - }], - 'del_fcs': [], - 'segment_id': 82, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:52:39', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.6', - 'node_type': 'sf_node', - 'egress': '02ebda8f-44e5-41ee-8d80-ec47b3c2732e', - 'next_group_id': None, - 'host_id': 'test6', - 'nsp': 256, - 'portchain_id': 'd92114e8-56df-4bd7-9cf2-fce5ac01c94f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'b7c69625-9cde-48dd-8858-5d773b002e73'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '32971131-e44c-4aad-85f9-7d9f10d07393' - }, { - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b7e8e42-b35d-4d49-8397-62088efe144f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': '7b718ad7-c2cc-4de0-9ac0-d5f4b6e975aa' - }], - 'id': u'c065e0c3-a904-4bac-adf2-f038b717c9c2' - }, { - 'nsi': 255, - 'ingress': None, - 'next_hops': [{ - 'local_endpoint': '10.0.0.6', - 'ingress': '9ac01d29-797a-4904-97a0-eecc7661b2ad', - 'weight': 1, - 'mac_address': '12:34:56:78:52:39' - }], - 'del_fcs': [], - 'segment_id': 82, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:41:cf', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.2', - 'node_type': 'src_node', - 'egress': '32971131-e44c-4aad-85f9-7d9f10d07393', - 'next_group_id': 1, - 'host_id': 'test1', - 'nsp': 256, - 'portchain_id': 'd92114e8-56df-4bd7-9cf2-fce5ac01c94f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'b7c69625-9cde-48dd-8858-5d773b002e73'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': ( - '32971131-e44c-4aad-85f9-7d9f10d07393') - }], - 'id': u'44c469bf-6c48-4f8f-bb4f-de87b44b02b6' - }, { - 'nsi': 253, - 'ingress': 'b7c69625-9cde-48dd-8858-5d773b002e73', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 82, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:36:e9', - 'network_type': 'gre', - 'local_endpoint': '10.0.0.3', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test2', - 'nsp': 256, - 'portchain_id': 'd92114e8-56df-4bd7-9cf2-fce5ac01c94f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - 'b7c69625-9cde-48dd-8858-5d773b002e73'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': ( - '32971131-e44c-4aad-85f9-7d9f10d07393') - }], - 'id': '4a61e567-4210-41d9-af82-e01b9da47230' - }, { - 'nsi': 253, - 'ingress': '2b7e8e42-b35d-4d49-8397-62088efe144f', - 'next_hops': None, - 'del_fcs': [], - 'segment_id': 82, - 'group_refcnt': 1, - 'mac_address': '12:34:56:78:51:9a', - 'network_type': 'gre', - 'local_endpoint': u'10.0.0.5', - 'node_type': 'dst_node', - 'egress': None, - 'next_group_id': None, - 'host_id': 'test4', - 'nsp': 256, - 'portchain_id': 'd92114e8-56df-4bd7-9cf2-fce5ac01c94f', - 'add_fcs': [{ - 'source_port_range_min': None, - 'destination_ip_prefix': None, - 'protocol': None, - 'ethertype': 'IPv4', - 'l7_parameters': {}, - 'source_port_range_max': None, - 'source_ip_prefix': None, - 'logical_destination_port': ( - '2b7e8e42-b35d-4d49-8397-62088efe144f'), - 'destination_port_range_min': None, - 'destination_port_range_max': None, - 'logical_source_port': ( - '7b718ad7-c2cc-4de0-9ac0-d5f4b6e975aa') - }], - 'id': '4a61e567-4210-41d9-af82-e01b9da47230' - }] - self.init_agent() - for port_id in self.port_mapping: - self.agent.sfc_treat_devices_added_updated(port_id) - self.assertItemsEqual( - self.added_flows, [{ - 'actions': 'resubmit(,5)', - 'dl_type': 34887, - 'priority': 10, - 'table': 0 - }, { - 'actions': 'resubmit(,30)', - 'dl_type': 34887, - 'priority': 10 - }, { - 'actions': 'output:1', - 'priority': 0, - 'table': 30 - }, { - 'actions': 'resubmit(,31)', - 'in_port': 1, - 'priority': 10, - 'table': 30 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:2' - ), - 'dl_type': 2048, - 'in_port': 44, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'group:1', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 0, - 'table': 31 - }, { - 'actions': 'pop_mpls:0x0800,output:45', - 'dl_dst': '00:01:02:03:06:11', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:36:e9,' - 'set_field:82->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65790, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65790,' - 'set_mpls_ttl:254,output:2' - ), - 'dl_type': 2048, - 'in_port': 43, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': ( - 'mod_dl_dst:12:34:56:78:51:9a,' - 'set_field:82->tun_id,output:[]' - ), - 'dl_type': 34887, - 'mpls_label': 65790, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 0, - 'table': 31, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }, { - 'actions': 'pop_mpls:0x0800,output:42', - 'dl_dst': '00:01:02:03:06:08', - 'dl_type': 34887, - 'mpls_label': 65791, - 'priority': 1, - 'table': 5 - }, { - 'actions': 'pop_mpls:0x0800,output:46', - 'dl_dst': '00:01:02:03:06:12', - 'dl_type': 34887, - 'mpls_label': 65790, - 'priority': 1, - 'table': 5 - }, { - 'actions': ( - 'push_mpls:0x8847,' - 'set_mpls_label:65791,' - 'set_mpls_ttl:255,output:2' - ), - 'dl_type': 2048, - 'in_port': 6, - 'nw_dst': '0.0.0.0/0.0.0.0', - 'nw_src': '0.0.0.0/0.0.0.0', - 'priority': 10, - 'table': 0, - 'tp_dst': '0/0x0', - 'tp_src': '0/0x0' - }] - ) - self.assertEqual( - self.group_mapping, { - 1: { - 'buckets': ( - 'bucket=weight=1,' - 'mod_dl_dst:12:34:56:78:52:39,' - 'set_field:82->tun_id,output:[]' - ), - 'group_id': 1, - 'type': 'select' - } - } - ) diff --git a/networking_sfc/tests/unit/services/sfc/common/__init__.py b/networking_sfc/tests/unit/services/sfc/common/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/services/sfc/common/test_ovs_ext_lib.py b/networking_sfc/tests/unit/services/sfc/common/test_ovs_ext_lib.py deleted file mode 100644 index 19e20cc..0000000 --- a/networking_sfc/tests/unit/services/sfc/common/test_ovs_ext_lib.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from neutron.common import exceptions -from neutron.tests import base - -from networking_sfc.services.sfc.common import ovs_ext_lib - - -class GetPortMaskTestCase(base.BaseTestCase): - def setUp(self): - super(GetPortMaskTestCase, self).setUp() - - def tearDown(self): - super(GetPortMaskTestCase, self).tearDown() - - def test_single_port(self): - masks = ovs_ext_lib.get_port_mask(100, 100) - self.assertEqual(masks, ['0x64/0xffff']) - - def test_invalid_min_port(self): - self.assertRaises( - exceptions.InvalidInput, - ovs_ext_lib.get_port_mask, - 0, 100 - ) - - def test_invalid_max_port(self): - self.assertRaises( - exceptions.InvalidInput, - ovs_ext_lib.get_port_mask, - 100, 65536 - ) - - def test_invalid_port_range(self): - self.assertRaises( - exceptions.InvalidInput, - ovs_ext_lib.get_port_mask, - 100, 99 - ) - - def test_one_port_mask(self): - masks = ovs_ext_lib.get_port_mask(100, 101) - self.assertEqual(masks, ['0x64/0xfffe']) - masks = ovs_ext_lib.get_port_mask(100, 103) - self.assertEqual(masks, ['0x64/0xfffc']) - masks = ovs_ext_lib.get_port_mask(32768, 65535) - self.assertEqual(masks, ['0x8000/0x8000']) - - def test_multi_port_masks(self): - masks = ovs_ext_lib.get_port_mask(101, 102) - self.assertEqual(masks, ['0x65/0xffff', '0x66/0xffff']) - masks = ovs_ext_lib.get_port_mask(101, 104) - self.assertEqual( - masks, - ['0x65/0xffff', '0x66/0xfffe', '0x68/0xffff'] - ) - masks = ovs_ext_lib.get_port_mask(1, 65535) - self.assertEqual( - masks, [ - '0x1/0xffff', - '0x2/0xfffe', - '0x4/0xfffc', - '0x8/0xfff8', - '0x10/0xfff0', - '0x20/0xffe0', - '0x40/0xffc0', - '0x80/0xff80', - '0x100/0xff00', - '0x200/0xfe00', - '0x400/0xfc00', - '0x800/0xf800', - '0x1000/0xf000', - '0x2000/0xe000', - '0x4000/0xc000', - '0x8000/0x8000' - ] - ) - masks = ovs_ext_lib.get_port_mask(32767, 65535) - self.assertEqual( - masks, ['0x7fff/0xffff', '0x8000/0x8000'] - ) diff --git a/networking_sfc/tests/unit/services/sfc/drivers/__init__.py b/networking_sfc/tests/unit/services/sfc/drivers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/services/sfc/drivers/ovs/__init__.py b/networking_sfc/tests/unit/services/sfc/drivers/ovs/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/networking_sfc/tests/unit/services/sfc/test_driver_manager.py b/networking_sfc/tests/unit/services/sfc/test_driver_manager.py deleted file mode 100644 index c247bf2..0000000 --- a/networking_sfc/tests/unit/services/sfc/test_driver_manager.py +++ /dev/null @@ -1,325 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import contextlib -import mock -import pkg_resources -import six -import stevedore - -from oslo_config import cfg - -from neutron.tests import base - -from networking_sfc.services.sfc.common import config as sfc_config -from networking_sfc.services.sfc.common import exceptions as sfc_exc -from networking_sfc.services.sfc import driver_manager as sfc_driver - - -class DriverManagerTestCase(base.BaseTestCase): - def setUp(self): - super(DriverManagerTestCase, self).setUp() - - @contextlib.contextmanager - def driver_manager_context(self, drivers): - cfg.CONF.register_opts(sfc_config.SFC_DRIVER_OPTS, 'sfc') - backup_driver_names = cfg.CONF.sfc.drivers - driver_names = [ - driver_name for driver_name in six.iterkeys(drivers) - ] - cfg.CONF.set_override('drivers', driver_names, 'sfc') - iter_entry_points = pkg_resources.iter_entry_points - find_entry_points = stevedore.ExtensionManager._find_entry_points - pkg_resources.iter_entry_points = mock.Mock() - stevedore.ExtensionManager._find_entry_points = mock.Mock() - driver_entry_points = [] - for driver_name in driver_names: - driver_class = mock.Mock() - ep = mock.Mock() - ep.name = driver_name - ep.resolve.return_value = driver_class - driver_class.return_value = drivers[driver_name] - drivers[driver_name].native_bulk_support = True - driver_entry_points.append(ep) - pkg_resources.iter_entry_points.return_value = driver_entry_points - stevedore.ExtensionManager._find_entry_points.return_value = ( - driver_entry_points - ) - yield sfc_driver.SfcDriverManager() - cfg.CONF.set_override('drivers', backup_driver_names, 'sfc') - pkg_resources.iter_entry_points = iter_entry_points - stevedore.ExtensionManager._find_entry_points = find_entry_points - - def test_initialize_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - manager.initialize() - mock_driver1.initialize.assert_called_once_with() - mock_driver2.initialize.assert_called_once_with() - - def test_create_port_chain_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.create_port_chain(mocked_context) - mock_driver1.create_port_chain.assert_called_once_with( - mocked_context) - mock_driver2.create_port_chain.assert_called_once_with( - mocked_context) - - def test_create_port_chain_exception(self): - mock_driver = mock.Mock() - mock_driver.create_port_chain = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.create_port_chain, mocked_context - ) - - def test_update_port_chain_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.update_port_chain(mocked_context) - mock_driver1.update_port_chain.assert_called_once_with( - mocked_context) - mock_driver2.update_port_chain.assert_called_once_with( - mocked_context) - - def test_update_port_chain_exception(self): - mock_driver = mock.Mock() - mock_driver.update_port_chain = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.update_port_chain, mocked_context - ) - - def test_delete_port_chain_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.delete_port_chain(mocked_context) - mock_driver1.delete_port_chain.assert_called_once_with( - mocked_context) - mock_driver2.delete_port_chain.assert_called_once_with( - mocked_context) - - def test_delete_port_chain_exception(self): - mock_driver = mock.Mock() - mock_driver.delete_port_chain = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.delete_port_chain, mocked_context - ) - - def test_create_port_pair_group_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.create_port_pair_group(mocked_context) - mock_driver1.create_port_pair_group.assert_called_once_with( - mocked_context) - mock_driver2.create_port_pair_group.assert_called_once_with( - mocked_context) - - def test_create_port_pair_group_exception(self): - mock_driver = mock.Mock() - mock_driver.create_port_pair_group = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.create_port_pair_group, mocked_context - ) - - def test_update_port_pair_group_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.update_port_pair_group(mocked_context) - mock_driver1.update_port_pair_group.assert_called_once_with( - mocked_context) - mock_driver2.update_port_pair_group.assert_called_once_with( - mocked_context) - - def test_update_port_pair_group_exception(self): - mock_driver = mock.Mock() - mock_driver.update_port_pair_group = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.update_port_pair_group, mocked_context - ) - - def test_delete_port_pair_group_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.delete_port_pair_group(mocked_context) - mock_driver1.delete_port_pair_group.assert_called_once_with( - mocked_context) - mock_driver2.delete_port_pair_group.assert_called_once_with( - mocked_context) - - def test_delete_port_pair_group_exception(self): - mock_driver = mock.Mock() - mock_driver.delete_port_pair_group = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.delete_port_pair_group, mocked_context - ) - - def test_create_port_pair_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.create_port_pair(mocked_context) - mock_driver1.create_port_pair.assert_called_once_with( - mocked_context) - mock_driver2.create_port_pair.assert_called_once_with( - mocked_context) - - def test_create_port_pair_exception(self): - mock_driver = mock.Mock() - mock_driver.create_port_pair = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.create_port_pair, mocked_context - ) - - def test_update_port_pair_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.update_port_pair(mocked_context) - mock_driver1.update_port_pair.assert_called_once_with( - mocked_context) - mock_driver2.update_port_pair.assert_called_once_with( - mocked_context) - - def test_update_port_pair_exception(self): - mock_driver = mock.Mock() - mock_driver.update_port_pair = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.update_port_pair, mocked_context - ) - - def test_delete_port_pair_called(self): - mock_driver1 = mock.Mock() - mock_driver2 = mock.Mock() - with self.driver_manager_context({ - 'dummy1': mock_driver1, - 'dummy2': mock_driver2 - }) as manager: - mocked_context = mock.Mock() - manager.delete_port_pair(mocked_context) - mock_driver1.delete_port_pair.assert_called_once_with( - mocked_context) - mock_driver2.delete_port_pair.assert_called_once_with( - mocked_context) - - def test_delete_port_pair_exception(self): - mock_driver = mock.Mock() - mock_driver.delete_port_pair = mock.Mock( - side_effect=sfc_exc.SfcException - ) - with self.driver_manager_context({ - 'dummy': mock_driver, - }) as manager: - mocked_context = mock.Mock() - self.assertRaises( - sfc_exc.SfcDriverError, - manager.delete_port_pair, mocked_context - ) diff --git a/networking_sfc/tests/unit/services/sfc/test_plugin.py b/networking_sfc/tests/unit/services/sfc/test_plugin.py deleted file mode 100644 index d265838..0000000 --- a/networking_sfc/tests/unit/services/sfc/test_plugin.py +++ /dev/null @@ -1,468 +0,0 @@ -# Copyright 2015 Futurewei. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import mock - -from networking_sfc.services.sfc.common import context as sfc_ctx -from networking_sfc.services.sfc.common import exceptions as sfc_exc -from networking_sfc.tests.unit.db import test_sfc_db - -SFC_PLUGIN_KLASS = ( - "networking_sfc.services.sfc.plugin.SfcPlugin" -) - - -class SfcPluginTestCase(test_sfc_db.SfcDbPluginTestCase): - def setUp(self, core_plugin=None, sfc_plugin=None, ext_mgr=None): - if not sfc_plugin: - sfc_plugin = SFC_PLUGIN_KLASS - self.driver_manager_p = mock.patch( - 'networking_sfc.services.sfc.driver_manager.SfcDriverManager' - ) - self.fake_driver_manager_class = self.driver_manager_p.start() - self.fake_driver_manager = mock.Mock() - self.fake_driver_manager_class.return_value = self.fake_driver_manager - self.plugin_context = None - super(SfcPluginTestCase, self).setUp( - core_plugin=core_plugin, sfc_plugin=sfc_plugin, - ext_mgr=ext_mgr - ) - - def _record_context(self, plugin_context): - self.plugin_context = plugin_context - - def test_create_port_chain_driver_manager_called(self): - self.fake_driver_manager.create_port_chain = mock.Mock( - side_effect=self._record_context) - with self.port_pair_group(port_pair_group={}) as pg: - with self.port_chain(port_chain={ - 'port_pair_groups': [pg['port_pair_group']['id']] - }) as pc: - driver_manager = self.fake_driver_manager - driver_manager.create_port_chain.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortChainContext - ) - self.assertIn('port_chain', pc) - self.assertEqual( - self.plugin_context.current, pc['port_chain']) - - def test_create_port_chain_driver_manager_exception(self): - self.fake_driver_manager.create_port_chain = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='create_port_chain' - ) - ) - with self.port_pair_group(port_pair_group={}) as pg: - self._create_port_chain( - self.fmt, - {'port_pair_groups': [pg['port_pair_group']['id']]}, - expected_res_status=500) - self._test_list_resources('port_chain', []) - self.fake_driver_manager.delete_port_chain.assert_called_once_with( - mock.ANY - ) - - def test_update_port_chain_driver_manager_called(self): - self.fake_driver_manager.update_port_chain = mock.Mock( - side_effect=self._record_context) - with self.port_pair_group(port_pair_group={}) as pg: - with self.port_chain(port_chain={ - 'name': 'test1', - 'port_pair_groups': [pg['port_pair_group']['id']] - }) as pc: - req = self.new_update_request( - 'port_chains', {'port_chain': {'name': 'test2'}}, - pc['port_chain']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - driver_manager = self.fake_driver_manager - driver_manager.update_port_chain.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortChainContext - ) - self.assertIn('port_chain', pc) - self.assertIn('port_chain', res) - self.assertEqual( - self.plugin_context.current, res['port_chain']) - self.assertEqual( - self.plugin_context.original, pc['port_chain']) - - def test_update_port_chain_driver_manager_exception(self): - self.fake_driver_manager.update_port_chain = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='update_port_chain' - ) - ) - with self.port_pair_group(port_pair_group={}) as pg: - with self.port_chain(port_chain={ - 'name': 'test1', - 'port_pair_groups': [pg['port_pair_group']['id']] - }) as pc: - self.assertIn('port_chain', pc) - original_port_chain = pc['port_chain'] - req = self.new_update_request( - 'port_chains', {'port_chain': {'name': 'test2'}}, - pc['port_chain']['id'] - ) - updated_port_chain = copy.copy(original_port_chain) - updated_port_chain['name'] = 'test2' - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - res = self._list('port_chains') - self.assertIn('port_chains', res) - self.assertItemsEqual( - res['port_chains'], [updated_port_chain]) - - def test_delete_port_chain_manager_called(self): - self.fake_driver_manager.delete_port_chain = mock.Mock( - side_effect=self._record_context) - with self.port_pair_group(port_pair_group={}) as pg: - with self.port_chain(port_chain={ - 'name': 'test1', - 'port_pair_groups': [pg['port_pair_group']['id']] - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_chains', pc['port_chain']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - driver_manager = self.fake_driver_manager - driver_manager.delete_port_chain.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortChainContext - ) - self.assertIn('port_chain', pc) - self.assertEqual(self.plugin_context.current, pc['port_chain']) - - def test_delete_port_chain_driver_manager_exception(self): - self.fake_driver_manager.delete_port_chain = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='delete_port_chain' - ) - ) - with self.port_pair_group(port_pair_group={ - }, do_delete=False) as pg: - with self.port_chain(port_chain={ - 'name': 'test1', - 'port_pair_groups': [pg['port_pair_group']['id']] - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_chains', pc['port_chain']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - self._test_list_resources('port_chain', [pc]) - - def test_create_port_pair_group_driver_manager_called(self): - self.fake_driver_manager.create_port_pair_group = mock.Mock( - side_effect=self._record_context) - with self.port_pair_group(port_pair_group={}) as pc: - fake_driver_manager = self.fake_driver_manager - fake_driver_manager.create_port_pair_group.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortPairGroupContext - ) - self.assertIn('port_pair_group', pc) - self.assertEqual( - self.plugin_context.current, pc['port_pair_group']) - - def test_create_port_pair_group_driver_manager_exception(self): - self.fake_driver_manager.create_port_pair_group = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='create_port_pair_group' - ) - ) - self._create_port_pair_group(self.fmt, {}, expected_res_status=500) - self._test_list_resources('port_pair_group', []) - driver_manager = self.fake_driver_manager - driver_manager.delete_port_pair_group.assert_called_once_with( - mock.ANY - ) - - def test_update_port_pair_group_driver_manager_called(self): - self.fake_driver_manager.update_port_pair_group = mock.Mock( - side_effect=self._record_context) - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }) as pc: - req = self.new_update_request( - 'port_pair_groups', {'port_pair_group': {'name': 'test2'}}, - pc['port_pair_group']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - driver_manager = self.fake_driver_manager - driver_manager.update_port_pair_group.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortPairGroupContext - ) - self.assertIn('port_pair_group', pc) - self.assertIn('port_pair_group', res) - self.assertEqual( - self.plugin_context.current, res['port_pair_group']) - self.assertEqual( - self.plugin_context.original, pc['port_pair_group']) - - def test_update_port_pair_group_driver_manager_exception(self): - self.fake_driver_manager.update_port_pair_group = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='update_port_pair_group' - ) - ) - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }) as pc: - self.assertIn('port_pair_group', pc) - original_port_pair_group = pc['port_pair_group'] - req = self.new_update_request( - 'port_pair_groups', {'port_pair_group': {'name': 'test2'}}, - pc['port_pair_group']['id'] - ) - updated_port_pair_group = copy.copy(original_port_pair_group) - updated_port_pair_group['name'] = 'test2' - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - res = self._list('port_pair_groups') - self.assertIn('port_pair_groups', res) - self.assertItemsEqual( - res['port_pair_groups'], [updated_port_pair_group]) - - def test_delete_port_pair_group_manager_called(self): - self.fake_driver_manager.delete_port_pair_group = mock.Mock( - side_effect=self._record_context) - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_pair_groups', pc['port_pair_group']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - driver_manager = self.fake_driver_manager - driver_manager.delete_port_pair_group.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortPairGroupContext - ) - self.assertIn('port_pair_group', pc) - self.assertEqual( - self.plugin_context.current, pc['port_pair_group']) - - def test_delete_port_pair_group_driver_manager_exception(self): - self.fake_driver_manager.delete_port_pair_group = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='delete_port_pair_group' - ) - ) - with self.port_pair_group(port_pair_group={ - 'name': 'test1' - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_pair_groups', pc['port_pair_group']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - self._test_list_resources('port_pair_group', [pc]) - - def test_create_port_pair_driver_manager_called(self): - self.fake_driver_manager.create_port_pair = mock.Mock( - side_effect=self._record_context) - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - driver_manager = self.fake_driver_manager - driver_manager.create_port_pair.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortPairContext - ) - self.assertIn('port_pair', pc) - self.assertEqual(self.plugin_context.current, pc['port_pair']) - - def test_create_port_pair_driver_manager_exception(self): - self.fake_driver_manager.create_port_pair = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='create_port_pair' - ) - ) - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - self._create_port_pair( - self.fmt, - { - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }, - expected_res_status=500) - self._test_list_resources('port_pair', []) - driver_manager = self.fake_driver_manager - driver_manager.delete_port_pair.assert_called_once_with( - mock.ANY - ) - - def test_update_port_pair_driver_manager_called(self): - self.fake_driver_manager.update_port_pair = mock.Mock( - side_effect=self._record_context) - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - req = self.new_update_request( - 'port_pairs', {'port_pair': {'name': 'test2'}}, - pc['port_pair']['id'] - ) - res = self.deserialize( - self.fmt, - req.get_response(self.ext_api) - ) - driver_manager = self.fake_driver_manager - driver_manager.update_port_pair.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortPairContext - ) - self.assertIn('port_pair', pc) - self.assertIn('port_pair', res) - self.assertEqual( - self.plugin_context.current, res['port_pair']) - self.assertEqual( - self.plugin_context.original, pc['port_pair']) - - def test_update_port_pair_driver_manager_exception(self): - self.fake_driver_manager.update_port_pair = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='update_port_pair' - ) - ) - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }) as pc: - self.assertIn('port_pair', pc) - original_port_pair = pc['port_pair'] - req = self.new_update_request( - 'port_pairs', {'port_pair': {'name': 'test2'}}, - pc['port_pair']['id'] - ) - updated_port_pair = copy.copy(original_port_pair) - updated_port_pair['name'] = 'test2' - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - res = self._list('port_pairs') - self.assertIn('port_pairs', res) - self.assertItemsEqual(res['port_pairs'], [updated_port_pair]) - - def test_delete_port_pair_manager_called(self): - self.fake_driver_manager.delete_port_pair = mock.Mock( - side_effect=self._record_context) - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_pairs', pc['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 204) - fake_driver_manager = self.fake_driver_manager - fake_driver_manager.delete_port_pair.assert_called_once_with( - mock.ANY - ) - self.assertIsInstance( - self.plugin_context, sfc_ctx.PortPairContext - ) - self.assertIn('port_pair', pc) - self.assertEqual(self.plugin_context.current, pc['port_pair']) - - def test_delete_port_pair_driver_manager_exception(self): - self.fake_driver_manager.delete_port_pair = mock.Mock( - side_effect=sfc_exc.SfcDriverError( - method='delete_port_pair' - ) - ) - with self.port( - name='port1', - device_id='default' - ) as src_port, self.port( - name='port2', - device_id='default' - ) as dst_port: - with self.port_pair(port_pair={ - 'name': 'test1', - 'ingress': src_port['port']['id'], - 'egress': dst_port['port']['id'] - }, do_delete=False) as pc: - req = self.new_delete_request( - 'port_pairs', pc['port_pair']['id'] - ) - res = req.get_response(self.ext_api) - self.assertEqual(res.status_int, 500) - self._test_list_resources('port_pair', [pc]) -- cgit 1.2.3-korg