]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Define bridge/port fixtures for OVS/LinuxBridge/Veth backends
authorCedric Brandily <zzelle@gmail.com>
Fri, 27 Feb 2015 14:08:23 +0000 (14:08 +0000)
committerCedric Brandily <zzelle@gmail.com>
Wed, 1 Apr 2015 15:01:06 +0000 (15:01 +0000)
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

neutron/tests/common/net_helpers.py
neutron/tests/functional/agent/linux/base.py
neutron/tests/functional/agent/linux/test_iptables_firewall.py
neutron/tests/functional/agent/linux/test_ovsdb_monitor.py
neutron/tests/functional/agent/test_l3_agent.py
neutron/tests/functional/agent/test_ovs_lib.py
neutron/tests/functional/cmd/test_netns_cleanup.py

index 5b4c9f93486fa2b23d0876f00c2f5c7c5547a362..4ccf06d2007ffddc54ebb45c31080a5fa763ae77 100644 (file)
 #    under the License.
 #
 
+import abc
+
 import fixtures
 import netaddr
+import six
 
+from neutron.agent.linux import bridge_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.openstack.common import uuidutils
 from neutron.tests import base as tests_base
@@ -62,6 +67,8 @@ class NamespaceFixture(fixtures.Fixture):
 
     :ivar ip_wrapper: created namespace
     :type ip_wrapper: IPWrapper
+    :ivar name: created namespace name
+    :type name: str
     """
 
     def __init__(self, prefix=NS_PREFIX):
@@ -108,3 +115,158 @@ class VethFixture(fixtures.Fixture):
                 # NOTE(cbrandily): It seems a veth is automagically deleted
                 # when a namespace owning a veth endpoint is deleted.
                 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()
index 01488646a81f4177b0e32fbfeaf0d5bf4f86e495..149c625efa79a9d49224ac6f6c19c1829dd7bf55 100644 (file)
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import netaddr
 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.common import base as common_base
 from neutron.tests.common import net_helpers
 from neutron.tests.functional import base as functional_base
 
 
-BR_PREFIX = 'test-br'
-PORT_PREFIX = 'test-port'
 MARK_VALUE = '0x1'
 MARK_MASK = '0xffffffff'
 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
 
 
-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):
 
     def _create_namespace(self, prefix=net_helpers.NS_PREFIX):
@@ -65,35 +52,6 @@ class BaseOVSLinuxTestCase(testscenarios.WithScenarios, BaseLinuxTestCase):
     def setUp(self):
         super(BaseOVSLinuxTestCase, self).setUp()
         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):
@@ -105,15 +63,14 @@ class BaseIPVethTestCase(BaseLinuxTestCase):
         device.addr.add(cidr)
         device.link.set_up()
 
-    def prepare_veth_pairs(self, src_ns_prefix=net_helpers.NS_PREFIX,
-                           dst_ns_prefix=net_helpers.NS_PREFIX):
+    def prepare_veth_pairs(self):
 
         src_addr = self.SRC_ADDRESS
         dst_addr = self.DST_ADDRESS
 
         src_veth, dst_veth = self.create_veth()
-        src_ns = self._create_namespace(src_ns_prefix)
-        dst_ns = self._create_namespace(dst_ns_prefix)
+        src_ns = self._create_namespace()
+        dst_ns = self._create_namespace()
         src_ns.add_device_to_namespace(src_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)
 
         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
index d0cfa18286c7f96be3ab8606505f79bfb1e37d64..6a8d02cf335d421ab83ecbe03c82c34cda01086b 100644 (file)
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from neutron.agent.linux import ip_lib
 from neutron.agent.linux import iptables_firewall
 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 helpers
 from oslo_config import cfg
 
 
-class IptablesFirewallTestCase(base.BaseBridgeTestCase):
+class IptablesFirewallTestCase(base.BaseIPVethTestCase):
     MAC_REAL = "fa:16:3e:9a:2f:49"
     MAC_SPOOFED = "fa:16:3e:9a:2f:48"
     FAKE_SECURITY_GROUP_ID = "fake_sg_id"
 
     def _set_src_mac(self, mac):
-        self.src_veth.link.set_down()
-        self.src_veth.link.set_address(mac)
-        self.src_veth.link.set_up()
+        self.src_port.link.set_down()
+        self.src_port.link.set_address(mac)
+        self.src_port.link.set_up()
 
     def setUp(self):
         cfg.CONF.register_opts(sg_cfg.security_group_opts, 'SECURITYGROUP')
         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(
-            self.bridge.namespace)
-        self.bridge.addif(self.src_br_veth.name)
-        self._set_ip_up(self.src_veth, '%s/24' % self.SRC_ADDRESS)
-        self.src_br_veth.link.set_up()
+        # FIXME(cbrandily): temporary, will be replaced by fake machines
+        self.src_ip_wrapper = self.useFixture(
+            net_helpers.NamespaceFixture()).ip_wrapper
 
-        self.dst_veth, self.dst_br_veth = self.create_veth_pairs(
-            self.bridge.namespace)
-        self.bridge.addif(self.dst_br_veth.name)
-        self._set_ip_up(self.dst_veth, '%s/24' % self.DST_ADDRESS)
-        self.dst_br_veth.link.set_up()
+        src_port_fixture = self.useFixture(
+            net_helpers.LinuxBridgePortFixture(
+                bridge, self.src_ip_wrapper.namespace))
+        self.src_port = src_port_fixture.port
+        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(
-            namespace=self.bridge.namespace)
+            namespace=bridge.namespace)
 
         self._set_src_mac(self.MAC_REAL)
 
-        self.src_port = {'admin_state_up': True,
-                         'device': self.src_br_veth.name,
-                         'device_owner': 'compute:None',
-                         'fixed_ips': [self.SRC_ADDRESS],
-                         'mac_address': self.MAC_REAL,
-                         'port_security_enabled': True,
-                         'security_groups': [self.FAKE_SECURITY_GROUP_ID],
-                         'status': 'ACTIVE'}
+        self.src_port_desc = {'admin_state_up': True,
+                              'device': src_port_fixture.br_port.name,
+                              'device_owner': 'compute:None',
+                              'fixed_ips': [self.SRC_ADDRESS],
+                              'mac_address': self.MAC_REAL,
+                              'port_security_enabled': True,
+                              'security_groups': [self.FAKE_SECURITY_GROUP_ID],
+                              'status': 'ACTIVE'}
 
     # setup firewall on bridge and send packet from src_veth and observe
     # if sent packet can be observed on dst_veth
     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
         sg_rules = [{'ethertype': 'IPv4', 'direction': 'ingress',
@@ -79,7 +84,7 @@ class IptablesFirewallTestCase(base.BaseBridgeTestCase):
             self.firewall.update_security_group_rules(
                                                 self.FAKE_SECURITY_GROUP_ID,
                                                 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)
 
         # modify the src_veth's MAC and test again
@@ -87,6 +92,6 @@ class IptablesFirewallTestCase(base.BaseBridgeTestCase):
         pinger.assert_no_ping(self.DST_ADDRESS)
 
         # update the port's port_security_enabled value and test again
-        self.src_port['port_security_enabled'] = False
-        self.firewall.update_port_filter(self.src_port)
+        self.src_port_desc['port_security_enabled'] = False
+        self.firewall.update_port_filter(self.src_port_desc)
         pinger.assert_ping(self.DST_ADDRESS)
index 4fe18ca0ece2a9cd3c9e2a62cdfcb7132c20483c..f93afeedf53c9fcfee9af28d4e0fc7d26211e86e 100644 (file)
@@ -27,6 +27,7 @@ from oslo_config import cfg
 
 from neutron.agent.linux import ovsdb_monitor
 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 import base as functional_base
 
@@ -46,7 +47,6 @@ class BaseMonitorTest(linux_base.BaseOVSLinuxTestCase):
                         root_helper=" ".join([functional_base.SUDO_CMD] * 2))
 
         self._check_test_requirements()
-        self.bridge = self.create_ovs_bridge()
 
     def _check_test_requirements(self):
         self.check_command(['ovsdb-client', 'list-dbs'],
@@ -102,7 +102,7 @@ class TestSimpleInterfaceMonitor(BaseMonitorTest):
                         'Initial call should always be true')
         self.assertFalse(self.monitor.has_updates,
                          '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
         while not self.monitor.has_updates:
             eventlet.sleep(0.01)
index 3a6a11f03519c57db366cb3347906ea9d28a555f..930ca5ad1835e48090c05e568a2318f1ea3d6e7b 100644 (file)
@@ -80,8 +80,8 @@ class L3AgentTestFramework(base.BaseOVSLinuxTestCase):
             'neutron.agent.linux.interface.OVSInterfaceDriver')
         conf.set_override('router_delete_namespaces', True)
 
-        br_int = self.create_ovs_bridge()
-        br_ex = self.create_ovs_bridge()
+        br_int = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
+        br_ex = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
         conf.set_override('ovs_integration_bridge', br_int.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)
         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)
-        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)
-        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)
 
         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])
         ip_cidr = net_helpers.increment_ip_cidr(router_ip_cidr)
         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,
                                           router_ip_cidr.partition('/')[0])
 
index ad5b1700433d7208b6403b3fc6e63803310ffc86..b411cba531b9cbcf89cb314ec8d98ff1ec807b96 100644 (file)
@@ -16,6 +16,7 @@
 import collections
 
 from neutron.agent.common import ovs_lib
+from neutron.agent.linux import ip_lib
 from neutron.tests.common import net_helpers
 from neutron.tests.functional.agent.linux import base
 
@@ -25,7 +26,8 @@ class OVSBridgeTestCase(base.BaseOVSLinuxTestCase):
     # good to also add the openflow-related functions
     def setUp(self):
         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):
         # Convert ((a, b), (c, d)) to {a: b, c: d} and add 'type' by default
@@ -118,7 +120,7 @@ class OVSBridgeTestCase(base.BaseOVSLinuxTestCase):
             "OpenFlow10")
 
     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(':', '')
         self.br.set_db_attribute('Bridge',
                                  self.br.br_name, 'datapath_id', dpid)
@@ -216,6 +218,11 @@ class OVSBridgeTestCase(base.BaseOVSLinuxTestCase):
 
 
 class OVSLibTestCase(base.BaseOVSLinuxTestCase):
+
+    def setUp(self):
+        super(OVSLibTestCase, self).setUp()
+        self.ovs = ovs_lib.BaseOVS()
+
     def test_bridge_lifecycle_baseovs(self):
         name = base.get_rand_name(prefix=net_helpers.BR_PREFIX)
         self.addCleanup(self.ovs.delete_bridge, name)
@@ -226,7 +233,9 @@ class OVSLibTestCase(base.BaseOVSLinuxTestCase):
         self.assertFalse(self.ovs.bridge_exists(name))
 
     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))
 
     def test_bridge_lifecycle_ovsbridge(self):
index e6405c90a9d8ce4adc608c9858dd86e80b91d577..92ca83fa4269d0716790b97969cbb06cbf15819c 100755 (executable)
@@ -19,13 +19,14 @@ from neutron.agent.l3 import agent as l3_agent
 from neutron.agent.linux import dhcp
 from neutron.agent.linux import ip_lib
 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'
 TEST_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
 
 
-class NetnsCleanupTest(base.BaseIPVethTestCase):
+class NetnsCleanupTest(base.BaseSudoTestCase):
     def setUp(self):
         super(NetnsCleanupTest, self).setUp()
 
@@ -44,16 +45,22 @@ class NetnsCleanupTest(base.BaseIPVethTestCase):
         self.config_parse(conf=self.conf, args=args)
 
     def test_cleanup_network_namespaces_cleans_dhcp_and_l3_namespaces(self):
-        l3_ns, dhcp_ns = self.prepare_veth_pairs(l3_agent.NS_PREFIX,
-                                                 dhcp.NS_PREFIX)
+        dhcp_namespace = self.useFixture(
+            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
         # tests, as otherwise cleanup will kill them all
-        self.get_namespaces.return_value = [l3_ns.namespace,
-                                            dhcp_ns.namespace]
+        self.get_namespaces.return_value = [l3_namespace, dhcp_namespace]
 
         netns_cleanup.cleanup_network_namespaces(self.conf)
 
         self.get_namespaces_p.stop()
         namespaces_now = ip_lib.IPWrapper.get_namespaces()
-        self.assertNotIn(l3_ns.namespace, namespaces_now)
-        self.assertNotIn(dhcp_ns.namespace, namespaces_now)
+        self.assertNotIn(l3_namespace, namespaces_now)
+        self.assertNotIn(dhcp_namespace, namespaces_now)