Define bridge/port fixtures for OVS/LinuxBridge/Veth backends

This change defines for OVS, LinuxBridge and veth[1] bridge and port
fixture classes in order to handle bridge and port setUp/cleanUp.

It allows to simplify BaseOVSLinuxTestCase[2] and remove
BaseBridgeTestCase[2].

[1] veth backend simulates a bridge with a veth
[2] in neutron.tests.functional.agent.linux.base

Change-Id: If34c9a8fb6fa584fb1e30173ec619d1aac9701f9
This commit is contained in:
Cedric Brandily 2015-02-27 14:08:23 +00:00
parent 0549c31b03
commit 748420518c
7 changed files with 245 additions and 117 deletions

View File

@ -13,10 +13,15 @@
# under the License. # under the License.
# #
import abc
import fixtures import fixtures
import netaddr import netaddr
import six
from neutron.agent.linux import bridge_lib
from neutron.agent.linux import ip_lib from neutron.agent.linux import ip_lib
from neutron.agent.linux import ovs_lib
from neutron.common import constants as n_const from neutron.common import constants as n_const
from neutron.openstack.common import uuidutils from neutron.openstack.common import uuidutils
from neutron.tests import base as tests_base from neutron.tests import base as tests_base
@ -62,6 +67,8 @@ class NamespaceFixture(fixtures.Fixture):
:ivar ip_wrapper: created namespace :ivar ip_wrapper: created namespace
:type ip_wrapper: IPWrapper :type ip_wrapper: IPWrapper
:ivar name: created namespace name
:type name: str
""" """
def __init__(self, prefix=NS_PREFIX): def __init__(self, prefix=NS_PREFIX):
@ -108,3 +115,158 @@ class VethFixture(fixtures.Fixture):
# NOTE(cbrandily): It seems a veth is automagically deleted # NOTE(cbrandily): It seems a veth is automagically deleted
# when a namespace owning a veth endpoint is deleted. # when a namespace owning a veth endpoint is deleted.
pass pass
@six.add_metaclass(abc.ABCMeta)
class PortFixture(fixtures.Fixture):
"""Create a port.
:ivar port: created port
:type port: IPDevice
:ivar bridge: port bridge
"""
def __init__(self, bridge=None, namespace=None):
self.bridge = bridge
self.namespace = namespace
@abc.abstractmethod
def _create_bridge_fixture(self):
pass
@abc.abstractmethod
def setUp(self):
super(PortFixture, self).setUp()
if not self.bridge:
self.bridge = self.useFixture(self._create_bridge_fixture()).bridge
class OVSBridgeFixture(fixtures.Fixture):
"""Create an OVS bridge.
:ivar bridge: created bridge
:type bridge: OVSBridge
"""
def setUp(self):
super(OVSBridgeFixture, self).setUp()
ovs = ovs_lib.BaseOVS()
self.bridge = common_base.create_resource(BR_PREFIX, ovs.add_bridge)
self.addCleanup(self.bridge.destroy)
class OVSPortFixture(PortFixture):
def _create_bridge_fixture(self):
return OVSBridgeFixture()
def setUp(self):
super(OVSPortFixture, self).setUp()
port_name = common_base.create_resource(PORT_PREFIX, self.create_port)
self.addCleanup(self.bridge.delete_port, port_name)
self.port = ip_lib.IPDevice(port_name)
ns_ip_wrapper = ip_lib.IPWrapper(self.namespace)
ns_ip_wrapper.add_device_to_namespace(self.port)
self.port.link.set_up()
def create_port(self, name):
self.bridge.add_port(name, ('type', 'internal'))
return name
class LinuxBridgeFixture(fixtures.Fixture):
"""Create a linux bridge.
:ivar bridge: created bridge
:type bridge: BridgeDevice
:ivar namespace: created bridge namespace
:type namespace: str
"""
def setUp(self):
super(LinuxBridgeFixture, self).setUp()
self.namespace = self.useFixture(NamespaceFixture()).name
self.bridge = common_base.create_resource(
BR_PREFIX,
bridge_lib.BridgeDevice.addbr,
namespace=self.namespace)
self.addCleanup(self.bridge.delbr)
self.bridge.link.set_up()
self.addCleanup(self.bridge.link.set_down)
class LinuxBridgePortFixture(PortFixture):
"""Create a linux bridge port.
:ivar port: created port
:type port: IPDevice
:ivar br_port: bridge side veth peer port
:type br_port: IPDevice
"""
def _create_bridge_fixture(self):
return LinuxBridgeFixture()
def setUp(self):
super(LinuxBridgePortFixture, self).setUp()
self.port, self.br_port = self.useFixture(VethFixture()).ports
# bridge side
br_ip_wrapper = ip_lib.IPWrapper(self.bridge.namespace)
br_ip_wrapper.add_device_to_namespace(self.br_port)
self.bridge.addif(self.br_port)
self.br_port.link.set_up()
# port side
ns_ip_wrapper = ip_lib.IPWrapper(self.namespace)
ns_ip_wrapper.add_device_to_namespace(self.port)
self.port.link.set_up()
class VethBridge(object):
def __init__(self, ports):
self.ports = ports
self.unallocated_ports = set(self.ports)
def allocate_port(self):
try:
return self.unallocated_ports.pop()
except KeyError:
tools.fail('All FakeBridge ports (%s) are already allocated.' %
len(self.ports))
class VethBridgeFixture(fixtures.Fixture):
"""Simulate a bridge with a veth.
:ivar bridge: created bridge
:type bridge: FakeBridge
"""
def setUp(self):
super(VethBridgeFixture, self).setUp()
ports = self.useFixture(VethFixture()).ports
self.bridge = VethBridge(ports)
class VethPortFixture(PortFixture):
"""Create a veth bridge port.
:ivar port: created port
:type port: IPDevice
"""
def _create_bridge_fixture(self):
return VethBridgeFixture()
def setUp(self):
super(VethPortFixture, self).setUp()
self.port = self.bridge.allocate_port()
ns_ip_wrapper = ip_lib.IPWrapper(self.namespace)
ns_ip_wrapper.add_device_to_namespace(self.port)
self.port.link.set_up()

View File

@ -12,21 +12,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import netaddr
import testscenarios import testscenarios
from neutron.agent.common import ovs_lib
from neutron.agent.linux import bridge_lib
from neutron.agent.linux import ip_lib
from neutron.common import constants as n_const
from neutron.tests import base as tests_base from neutron.tests import base as tests_base
from neutron.tests.common import base as common_base
from neutron.tests.common import net_helpers from neutron.tests.common import net_helpers
from neutron.tests.functional import base as functional_base from neutron.tests.functional import base as functional_base
BR_PREFIX = 'test-br'
PORT_PREFIX = 'test-port'
MARK_VALUE = '0x1' MARK_VALUE = '0x1'
MARK_MASK = '0xffffffff' MARK_MASK = '0xffffffff'
ICMP_MARK_RULE = ('-j MARK --set-xmark %(value)s/%(mask)s' ICMP_MARK_RULE = ('-j MARK --set-xmark %(value)s/%(mask)s'
@ -39,11 +31,6 @@ ICMP_BLOCK_RULE = '-p icmp -j DROP'
get_rand_name = tests_base.get_rand_name get_rand_name = tests_base.get_rand_name
def get_rand_bridge_name():
return get_rand_name(prefix=BR_PREFIX,
max_length=n_const.DEVICE_NAME_MAX_LEN)
class BaseLinuxTestCase(functional_base.BaseSudoTestCase): class BaseLinuxTestCase(functional_base.BaseSudoTestCase):
def _create_namespace(self, prefix=net_helpers.NS_PREFIX): def _create_namespace(self, prefix=net_helpers.NS_PREFIX):
@ -65,35 +52,6 @@ class BaseOVSLinuxTestCase(testscenarios.WithScenarios, BaseLinuxTestCase):
def setUp(self): def setUp(self):
super(BaseOVSLinuxTestCase, self).setUp() super(BaseOVSLinuxTestCase, self).setUp()
self.config(group='OVS', ovsdb_interface=self.ovsdb_interface) self.config(group='OVS', ovsdb_interface=self.ovsdb_interface)
self.ovs = ovs_lib.BaseOVS()
self.ip = ip_lib.IPWrapper()
def create_ovs_bridge(self, br_prefix=BR_PREFIX):
br = common_base.create_resource(br_prefix, self.ovs.add_bridge)
self.addCleanup(br.destroy)
return br
def create_ovs_port_in_ns(self, br, ns):
def create_port(name):
br.replace_port(name, ('type', 'internal'))
self.addCleanup(br.delete_port, name)
return name
port_name = common_base.create_resource(PORT_PREFIX, create_port)
port_dev = self.ip.device(port_name)
ns.add_device_to_namespace(port_dev)
port_dev.link.set_up()
return port_dev
def bind_namespace_to_cidr(self, namespace, br, ip_cidr):
"""Bind namespace to cidr (on layer2 and 3).
Bind the namespace to a subnet by creating an ovs port in the namespace
and configuring port ip.
"""
net = netaddr.IPNetwork(ip_cidr)
port_dev = self.create_ovs_port_in_ns(br, namespace)
port_dev.addr.add(str(net))
return port_dev
class BaseIPVethTestCase(BaseLinuxTestCase): class BaseIPVethTestCase(BaseLinuxTestCase):
@ -105,15 +63,14 @@ class BaseIPVethTestCase(BaseLinuxTestCase):
device.addr.add(cidr) device.addr.add(cidr)
device.link.set_up() device.link.set_up()
def prepare_veth_pairs(self, src_ns_prefix=net_helpers.NS_PREFIX, def prepare_veth_pairs(self):
dst_ns_prefix=net_helpers.NS_PREFIX):
src_addr = self.SRC_ADDRESS src_addr = self.SRC_ADDRESS
dst_addr = self.DST_ADDRESS dst_addr = self.DST_ADDRESS
src_veth, dst_veth = self.create_veth() src_veth, dst_veth = self.create_veth()
src_ns = self._create_namespace(src_ns_prefix) src_ns = self._create_namespace()
dst_ns = self._create_namespace(dst_ns_prefix) dst_ns = self._create_namespace()
src_ns.add_device_to_namespace(src_veth) src_ns.add_device_to_namespace(src_veth)
dst_ns.add_device_to_namespace(dst_veth) dst_ns.add_device_to_namespace(dst_veth)
@ -121,25 +78,3 @@ class BaseIPVethTestCase(BaseLinuxTestCase):
self._set_ip_up(dst_veth, '%s/24' % dst_addr) self._set_ip_up(dst_veth, '%s/24' % dst_addr)
return src_ns, dst_ns return src_ns, dst_ns
class BaseBridgeTestCase(BaseIPVethTestCase):
def create_veth_pairs(self, dst_namespace):
src_ns = self._create_namespace()
dst_ns = ip_lib.IPWrapper(dst_namespace)
src_veth, dst_veth = self.create_veth()
src_ns.add_device_to_namespace(src_veth)
dst_ns.add_device_to_namespace(dst_veth)
return src_veth, dst_veth
def create_bridge(self, br_ns=None):
br_ns = br_ns or self._create_namespace()
br_name = get_rand_bridge_name()
bridge = bridge_lib.BridgeDevice.addbr(br_name, br_ns.namespace)
self.addCleanup(bridge.delbr)
bridge.link.set_up()
self.addCleanup(bridge.link.set_down)
return bridge

View File

@ -16,59 +16,64 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from neutron.agent.linux import ip_lib
from neutron.agent.linux import iptables_firewall from neutron.agent.linux import iptables_firewall
from neutron.agent import securitygroups_rpc as sg_cfg from neutron.agent import securitygroups_rpc as sg_cfg
from neutron.tests.common import net_helpers
from neutron.tests.functional.agent.linux import base from neutron.tests.functional.agent.linux import base
from neutron.tests.functional.agent.linux import helpers from neutron.tests.functional.agent.linux import helpers
from oslo_config import cfg from oslo_config import cfg
class IptablesFirewallTestCase(base.BaseBridgeTestCase): class IptablesFirewallTestCase(base.BaseIPVethTestCase):
MAC_REAL = "fa:16:3e:9a:2f:49" MAC_REAL = "fa:16:3e:9a:2f:49"
MAC_SPOOFED = "fa:16:3e:9a:2f:48" MAC_SPOOFED = "fa:16:3e:9a:2f:48"
FAKE_SECURITY_GROUP_ID = "fake_sg_id" FAKE_SECURITY_GROUP_ID = "fake_sg_id"
def _set_src_mac(self, mac): def _set_src_mac(self, mac):
self.src_veth.link.set_down() self.src_port.link.set_down()
self.src_veth.link.set_address(mac) self.src_port.link.set_address(mac)
self.src_veth.link.set_up() self.src_port.link.set_up()
def setUp(self): def setUp(self):
cfg.CONF.register_opts(sg_cfg.security_group_opts, 'SECURITYGROUP') cfg.CONF.register_opts(sg_cfg.security_group_opts, 'SECURITYGROUP')
super(IptablesFirewallTestCase, self).setUp() super(IptablesFirewallTestCase, self).setUp()
self.bridge = self.create_bridge() bridge = self.useFixture(net_helpers.LinuxBridgeFixture()).bridge
self.src_veth, self.src_br_veth = self.create_veth_pairs( # FIXME(cbrandily): temporary, will be replaced by fake machines
self.bridge.namespace) self.src_ip_wrapper = self.useFixture(
self.bridge.addif(self.src_br_veth.name) net_helpers.NamespaceFixture()).ip_wrapper
self._set_ip_up(self.src_veth, '%s/24' % self.SRC_ADDRESS)
self.src_br_veth.link.set_up()
self.dst_veth, self.dst_br_veth = self.create_veth_pairs( src_port_fixture = self.useFixture(
self.bridge.namespace) net_helpers.LinuxBridgePortFixture(
self.bridge.addif(self.dst_br_veth.name) bridge, self.src_ip_wrapper.namespace))
self._set_ip_up(self.dst_veth, '%s/24' % self.DST_ADDRESS) self.src_port = src_port_fixture.port
self.dst_br_veth.link.set_up() self._set_ip_up(self.src_port, '%s/24' % self.SRC_ADDRESS)
self.dst_ip_wrapper = self.useFixture(
net_helpers.NamespaceFixture()).ip_wrapper
self.dst_port = self.useFixture(
net_helpers.LinuxBridgePortFixture(
bridge, self.dst_ip_wrapper.namespace)).port
self._set_ip_up(self.dst_port, '%s/24' % self.DST_ADDRESS)
self.firewall = iptables_firewall.IptablesFirewallDriver( self.firewall = iptables_firewall.IptablesFirewallDriver(
namespace=self.bridge.namespace) namespace=bridge.namespace)
self._set_src_mac(self.MAC_REAL) self._set_src_mac(self.MAC_REAL)
self.src_port = {'admin_state_up': True, self.src_port_desc = {'admin_state_up': True,
'device': self.src_br_veth.name, 'device': src_port_fixture.br_port.name,
'device_owner': 'compute:None', 'device_owner': 'compute:None',
'fixed_ips': [self.SRC_ADDRESS], 'fixed_ips': [self.SRC_ADDRESS],
'mac_address': self.MAC_REAL, 'mac_address': self.MAC_REAL,
'port_security_enabled': True, 'port_security_enabled': True,
'security_groups': [self.FAKE_SECURITY_GROUP_ID], 'security_groups': [self.FAKE_SECURITY_GROUP_ID],
'status': 'ACTIVE'} 'status': 'ACTIVE'}
# setup firewall on bridge and send packet from src_veth and observe # setup firewall on bridge and send packet from src_veth and observe
# if sent packet can be observed on dst_veth # if sent packet can be observed on dst_veth
def test_port_sec_within_firewall(self): def test_port_sec_within_firewall(self):
pinger = helpers.Pinger(ip_lib.IPWrapper(self.src_veth.namespace)) pinger = helpers.Pinger(self.src_ip_wrapper)
# update the sg_group to make ping pass # update the sg_group to make ping pass
sg_rules = [{'ethertype': 'IPv4', 'direction': 'ingress', sg_rules = [{'ethertype': 'IPv4', 'direction': 'ingress',
@ -79,7 +84,7 @@ class IptablesFirewallTestCase(base.BaseBridgeTestCase):
self.firewall.update_security_group_rules( self.firewall.update_security_group_rules(
self.FAKE_SECURITY_GROUP_ID, self.FAKE_SECURITY_GROUP_ID,
sg_rules) sg_rules)
self.firewall.prepare_port_filter(self.src_port) self.firewall.prepare_port_filter(self.src_port_desc)
pinger.assert_ping(self.DST_ADDRESS) pinger.assert_ping(self.DST_ADDRESS)
# modify the src_veth's MAC and test again # modify the src_veth's MAC and test again
@ -87,6 +92,6 @@ class IptablesFirewallTestCase(base.BaseBridgeTestCase):
pinger.assert_no_ping(self.DST_ADDRESS) pinger.assert_no_ping(self.DST_ADDRESS)
# update the port's port_security_enabled value and test again # update the port's port_security_enabled value and test again
self.src_port['port_security_enabled'] = False self.src_port_desc['port_security_enabled'] = False
self.firewall.update_port_filter(self.src_port) self.firewall.update_port_filter(self.src_port_desc)
pinger.assert_ping(self.DST_ADDRESS) pinger.assert_ping(self.DST_ADDRESS)

View File

@ -27,6 +27,7 @@ from oslo_config import cfg
from neutron.agent.linux import ovsdb_monitor from neutron.agent.linux import ovsdb_monitor
from neutron.agent.linux import utils from neutron.agent.linux import utils
from neutron.tests.common import net_helpers
from neutron.tests.functional.agent.linux import base as linux_base from neutron.tests.functional.agent.linux import base as linux_base
from neutron.tests.functional import base as functional_base from neutron.tests.functional import base as functional_base
@ -46,7 +47,6 @@ class BaseMonitorTest(linux_base.BaseOVSLinuxTestCase):
root_helper=" ".join([functional_base.SUDO_CMD] * 2)) root_helper=" ".join([functional_base.SUDO_CMD] * 2))
self._check_test_requirements() self._check_test_requirements()
self.bridge = self.create_ovs_bridge()
def _check_test_requirements(self): def _check_test_requirements(self):
self.check_command(['ovsdb-client', 'list-dbs'], self.check_command(['ovsdb-client', 'list-dbs'],
@ -102,7 +102,7 @@ class TestSimpleInterfaceMonitor(BaseMonitorTest):
'Initial call should always be true') 'Initial call should always be true')
self.assertFalse(self.monitor.has_updates, self.assertFalse(self.monitor.has_updates,
'has_updates without port addition should be False') 'has_updates without port addition should be False')
self.create_ovs_port_in_ns(self.bridge, self.ip) self.useFixture(net_helpers.OVSPortFixture())
# has_updates after port addition should become True # has_updates after port addition should become True
while not self.monitor.has_updates: while not self.monitor.has_updates:
eventlet.sleep(0.01) eventlet.sleep(0.01)

View File

@ -80,8 +80,8 @@ class L3AgentTestFramework(base.BaseOVSLinuxTestCase):
'neutron.agent.linux.interface.OVSInterfaceDriver') 'neutron.agent.linux.interface.OVSInterfaceDriver')
conf.set_override('router_delete_namespaces', True) conf.set_override('router_delete_namespaces', True)
br_int = self.create_ovs_bridge() br_int = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
br_ex = self.create_ovs_bridge() br_ex = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
conf.set_override('ovs_integration_bridge', br_int.br_name) conf.set_override('ovs_integration_bridge', br_int.br_name)
conf.set_override('external_network_bridge', br_ex.br_name) conf.set_override('external_network_bridge', br_ex.br_name)
@ -656,12 +656,18 @@ class L3AgentTestCase(L3AgentTestFramework):
self._add_fip(router, dst_fip, fixed_address=dst_ip) self._add_fip(router, dst_fip, fixed_address=dst_ip)
router.process(self.agent) router.process(self.agent)
src_ns = self._create_namespace(prefix='test-src-')
dst_ns = self._create_namespace(prefix='test-dst-')
br_int = get_ovs_bridge(self.agent.conf.ovs_integration_bridge) br_int = get_ovs_bridge(self.agent.conf.ovs_integration_bridge)
src_port = self.bind_namespace_to_cidr(src_ns, br_int, src_ip_cidr)
# FIXME(cbrandily): temporary, will be replaced by fake machines
src_ns = self._create_namespace(prefix='test-src-')
src_port = self.useFixture(
net_helpers.OVSPortFixture(br_int, src_ns.namespace)).port
src_port.addr.add(src_ip_cidr)
net_helpers.set_namespace_gateway(src_port, router_ip) net_helpers.set_namespace_gateway(src_port, router_ip)
dst_port = self.bind_namespace_to_cidr(dst_ns, br_int, dst_ip_cidr) dst_ns = self._create_namespace(prefix='test-dst-')
dst_port = self.useFixture(
net_helpers.OVSPortFixture(br_int, dst_ns.namespace)).port
dst_port.addr.add(dst_ip_cidr)
net_helpers.set_namespace_gateway(dst_port, router_ip) net_helpers.set_namespace_gateway(dst_port, router_ip)
protocol_port = helpers.get_free_namespace_port(dst_ns) protocol_port = helpers.get_free_namespace_port(dst_ns)
@ -767,7 +773,11 @@ class MetadataL3AgentTestCase(L3AgentTestFramework):
router_ip_cidr = self._port_first_ip_cidr(router.internal_ports[0]) router_ip_cidr = self._port_first_ip_cidr(router.internal_ports[0])
ip_cidr = net_helpers.increment_ip_cidr(router_ip_cidr) ip_cidr = net_helpers.increment_ip_cidr(router_ip_cidr)
br_int = get_ovs_bridge(self.agent.conf.ovs_integration_bridge) br_int = get_ovs_bridge(self.agent.conf.ovs_integration_bridge)
port = self.bind_namespace_to_cidr(client_ns, br_int, ip_cidr)
# FIXME(cbrandily): temporary, will be replaced by a fake machine
port = self.useFixture(
net_helpers.OVSPortFixture(br_int, client_ns.namespace)).port
port.addr.add(ip_cidr)
net_helpers.set_namespace_gateway(port, net_helpers.set_namespace_gateway(port,
router_ip_cidr.partition('/')[0]) router_ip_cidr.partition('/')[0])

View File

@ -16,6 +16,7 @@
import collections import collections
from neutron.agent.common import ovs_lib from neutron.agent.common import ovs_lib
from neutron.agent.linux import ip_lib
from neutron.tests.common import net_helpers from neutron.tests.common import net_helpers
from neutron.tests.functional.agent.linux import base from neutron.tests.functional.agent.linux import base
@ -25,7 +26,8 @@ class OVSBridgeTestCase(base.BaseOVSLinuxTestCase):
# good to also add the openflow-related functions # good to also add the openflow-related functions
def setUp(self): def setUp(self):
super(OVSBridgeTestCase, self).setUp() super(OVSBridgeTestCase, self).setUp()
self.br = self.create_ovs_bridge() self.ovs = ovs_lib.BaseOVS()
self.br = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
def create_ovs_port(self, *interface_attrs): def create_ovs_port(self, *interface_attrs):
# Convert ((a, b), (c, d)) to {a: b, c: d} and add 'type' by default # Convert ((a, b), (c, d)) to {a: b, c: d} and add 'type' by default
@ -118,7 +120,7 @@ class OVSBridgeTestCase(base.BaseOVSLinuxTestCase):
"OpenFlow10") "OpenFlow10")
def test_get_datapath_id(self): def test_get_datapath_id(self):
brdev = self.ip.device(self.br.br_name) brdev = ip_lib.IPDevice(self.br.br_name)
dpid = brdev.link.attributes['link/ether'].replace(':', '') dpid = brdev.link.attributes['link/ether'].replace(':', '')
self.br.set_db_attribute('Bridge', self.br.set_db_attribute('Bridge',
self.br.br_name, 'datapath_id', dpid) self.br.br_name, 'datapath_id', dpid)
@ -216,6 +218,11 @@ class OVSBridgeTestCase(base.BaseOVSLinuxTestCase):
class OVSLibTestCase(base.BaseOVSLinuxTestCase): class OVSLibTestCase(base.BaseOVSLinuxTestCase):
def setUp(self):
super(OVSLibTestCase, self).setUp()
self.ovs = ovs_lib.BaseOVS()
def test_bridge_lifecycle_baseovs(self): def test_bridge_lifecycle_baseovs(self):
name = base.get_rand_name(prefix=net_helpers.BR_PREFIX) name = base.get_rand_name(prefix=net_helpers.BR_PREFIX)
self.addCleanup(self.ovs.delete_bridge, name) self.addCleanup(self.ovs.delete_bridge, name)
@ -226,7 +233,9 @@ class OVSLibTestCase(base.BaseOVSLinuxTestCase):
self.assertFalse(self.ovs.bridge_exists(name)) self.assertFalse(self.ovs.bridge_exists(name))
def test_get_bridges(self): def test_get_bridges(self):
bridges = {self.create_ovs_bridge().br_name for i in range(5)} bridges = {
self.useFixture(net_helpers.OVSBridgeFixture()).bridge.br_name
for i in range(5)}
self.assertTrue(set(self.ovs.get_bridges()).issuperset(bridges)) self.assertTrue(set(self.ovs.get_bridges()).issuperset(bridges))
def test_bridge_lifecycle_ovsbridge(self): def test_bridge_lifecycle_ovsbridge(self):

View File

@ -19,13 +19,14 @@ from neutron.agent.l3 import agent as l3_agent
from neutron.agent.linux import dhcp from neutron.agent.linux import dhcp
from neutron.agent.linux import ip_lib from neutron.agent.linux import ip_lib
from neutron.cmd import netns_cleanup from neutron.cmd import netns_cleanup
from neutron.tests.functional.agent.linux import base from neutron.tests.common import net_helpers
from neutron.tests.functional import base
GET_NAMESPACES = 'neutron.agent.linux.ip_lib.IPWrapper.get_namespaces' GET_NAMESPACES = 'neutron.agent.linux.ip_lib.IPWrapper.get_namespaces'
TEST_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver' TEST_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
class NetnsCleanupTest(base.BaseIPVethTestCase): class NetnsCleanupTest(base.BaseSudoTestCase):
def setUp(self): def setUp(self):
super(NetnsCleanupTest, self).setUp() super(NetnsCleanupTest, self).setUp()
@ -44,16 +45,22 @@ class NetnsCleanupTest(base.BaseIPVethTestCase):
self.config_parse(conf=self.conf, args=args) self.config_parse(conf=self.conf, args=args)
def test_cleanup_network_namespaces_cleans_dhcp_and_l3_namespaces(self): def test_cleanup_network_namespaces_cleans_dhcp_and_l3_namespaces(self):
l3_ns, dhcp_ns = self.prepare_veth_pairs(l3_agent.NS_PREFIX, dhcp_namespace = self.useFixture(
dhcp.NS_PREFIX) net_helpers.NamespaceFixture(dhcp.NS_PREFIX)).name
l3_namespace = self.useFixture(
net_helpers.NamespaceFixture(l3_agent.NS_PREFIX)).name
bridge = self.useFixture(
net_helpers.VethPortFixture(namespace=dhcp_namespace)).bridge
self.useFixture(
net_helpers.VethPortFixture(bridge, l3_namespace))
# we scope the get_namespaces to our own ones not to affect other # we scope the get_namespaces to our own ones not to affect other
# tests, as otherwise cleanup will kill them all # tests, as otherwise cleanup will kill them all
self.get_namespaces.return_value = [l3_ns.namespace, self.get_namespaces.return_value = [l3_namespace, dhcp_namespace]
dhcp_ns.namespace]
netns_cleanup.cleanup_network_namespaces(self.conf) netns_cleanup.cleanup_network_namespaces(self.conf)
self.get_namespaces_p.stop() self.get_namespaces_p.stop()
namespaces_now = ip_lib.IPWrapper.get_namespaces() namespaces_now = ip_lib.IPWrapper.get_namespaces()
self.assertNotIn(l3_ns.namespace, namespaces_now) self.assertNotIn(l3_namespace, namespaces_now)
self.assertNotIn(dhcp_ns.namespace, namespaces_now) self.assertNotIn(dhcp_namespace, namespaces_now)