From 0f471be1de5aadc935c3b48625193dc23360e467 Mon Sep 17 00:00:00 2001 From: Cedric Brandily Date: Mon, 26 Oct 2015 09:19:26 +0900 Subject: [PATCH] Optimize interface_exists_on_bridge Currently interface_exists_on_bridge[1] lists all files in a folder and searchs for the file associated to the interface. This change proposes to look for the file existence directly. [1] neutron.plugins.ml2.drivers.linuxbridge.agent.linuxbridge_neutron_agent Closes-Bug: #1509890 Change-Id: I23cd1edc92912b35bdc23ba0af2318b86f2cfd48 --- .../agent/linuxbridge_neutron_agent.py | 11 +++++----- neutron/tests/common/net_helpers.py | 8 ++++++-- .../functional/agent/test_l2_lb_agent.py | 20 +++++++++++++++++++ .../agent/test_linuxbridge_neutron_agent.py | 5 +++-- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py index 8b75c7c7bd4..76e4f1a721b 100644 --- a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py @@ -62,6 +62,7 @@ BRIDGE_NAME_PREFIX = "brq" # NOTE(toabctl): Don't use /sys/devices/virtual/net here because not all tap # devices are listed here (i.e. when using Xen) BRIDGE_FS = "/sys/class/net/" +BRIDGE_INTERFACE_FS = BRIDGE_FS + "%(bridge)s/brif/%(interface)s" BRIDGE_INTERFACES_FS = BRIDGE_FS + "%s/brif/" BRIDGE_PORT_FS_FOR_DEVICE = BRIDGE_FS + "%s/brport" VXLAN_INTERFACE_PREFIX = "vxlan-" @@ -119,12 +120,10 @@ class LinuxBridgeManager(object): sys.exit(1) return device - def interface_exists_on_bridge(self, bridge, interface): - directory = '/sys/class/net/%s/brif' % bridge - for filename in os.listdir(directory): - if filename == interface: - return True - return False + @staticmethod + def interface_exists_on_bridge(bridge, interface): + return os.path.exists( + BRIDGE_INTERFACE_FS % {'bridge': bridge, 'interface': interface}) def get_existing_bridge_name(self, physical_network): if not physical_network: diff --git a/neutron/tests/common/net_helpers.py b/neutron/tests/common/net_helpers.py index 7750ecc7e27..9171f105c05 100644 --- a/neutron/tests/common/net_helpers.py +++ b/neutron/tests/common/net_helpers.py @@ -43,6 +43,8 @@ from neutron.tests import base as tests_base from neutron.tests.common import base as common_base from neutron.tests import tools +UNDEFINED = object() + NS_PREFIX = 'test-' BR_PREFIX = 'test-br' PORT_PREFIX = 'test-port' @@ -527,12 +529,14 @@ class LinuxBridgeFixture(fixtures.Fixture): :type namespace: str """ - def __init__(self, prefix=BR_PREFIX): + def __init__(self, prefix=BR_PREFIX, namespace=UNDEFINED): super(LinuxBridgeFixture, self).__init__() self.prefix = prefix + self.namespace = namespace def _setUp(self): - self.namespace = self.useFixture(NamespaceFixture()).name + if self.namespace is UNDEFINED: + self.namespace = self.useFixture(NamespaceFixture()).name self.bridge = common_base.create_resource( self.prefix, bridge_lib.BridgeDevice.addbr, diff --git a/neutron/tests/functional/agent/test_l2_lb_agent.py b/neutron/tests/functional/agent/test_l2_lb_agent.py index 5dfdacd404b..ebabc49051e 100644 --- a/neutron/tests/functional/agent/test_l2_lb_agent.py +++ b/neutron/tests/functional/agent/test_l2_lb_agent.py @@ -19,6 +19,7 @@ import testtools from neutron.plugins.ml2.drivers.linuxbridge.agent import \ linuxbridge_neutron_agent +from neutron.tests.common import net_helpers from neutron.tests.functional.agent.linux import test_ip_lib LOG = logging.getLogger(__name__) @@ -34,6 +35,13 @@ class LinuxBridgeAgentTests(test_ip_lib.IpLibTestFramework): mock.patch('neutron.agent.rpc.PluginReportStateAPI').start() cfg.CONF.set_override('enable_vxlan', False, 'VXLAN') + def create_bridge_port_fixture(self): + bridge = self.useFixture( + net_helpers.LinuxBridgeFixture(namespace=None)).bridge + port_fixture = self.useFixture( + net_helpers.LinuxBridgePortFixture(bridge)) + return port_fixture + def test_validate_interface_mappings(self): mappings = {'physnet1': 'int1', 'physnet2': 'int2'} with testtools.ExpectedException(SystemExit): @@ -56,3 +64,15 @@ class LinuxBridgeAgentTests(test_ip_lib.IpLibTestFramework): self.generate_device_details()._replace(namespace=None, name='br-eth1')) lba.LinuxBridgeManager(mappings, {}) + + def test_interface_exists_on_bridge(self): + port_fixture = self.create_bridge_port_fixture() + self.assertTrue( + lba.LinuxBridgeManager.interface_exists_on_bridge( + port_fixture.bridge.name, port_fixture.br_port.name)) + + def test_interface_exists_not_on_bridge(self): + port_fixture = self.create_bridge_port_fixture() + self.assertFalse( + lba.LinuxBridgeManager.interface_exists_on_bridge( + port_fixture.bridge.name, port_fixture.port.name)) diff --git a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py index d5eea954ee0..3c5ee4131dc 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py @@ -402,8 +402,9 @@ class TestLinuxBridgeManager(base.BaseTestCase): exit.assert_called_once_with(1) def test_interface_exists_on_bridge(self): - with mock.patch.object(os, 'listdir') as listdir_fn: - listdir_fn.return_value = ["abc"] + with mock.patch.object(os.path, 'exists') as exists_fn: + exists_fn.side_effect = ( + lambda p: p == '/sys/class/net/br-int/brif/abc') self.assertTrue( self.lbm.interface_exists_on_bridge("br-int", "abc") )