]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Merge open source plugin test code modules
authorMaru Newby <marun@redhat.com>
Mon, 6 Apr 2015 21:51:23 +0000 (21:51 +0000)
committerMaru Newby <marun@redhat.com>
Mon, 6 Apr 2015 23:28:45 +0000 (23:28 +0000)
The unit test reorg is about moving files around so a test module is
clearly associated with the code module it targets, but the test
modules in this change needed to be manually merged because they both
targeted the same module.

Change-Id: I80f4b97fadd318896e7fa4e7e7e939f924127b2a
Partial-Bug: #1440834

neutron/tests/unit/plugins/ml2/db/test_ml2_db.py
neutron/tests/unit/plugins/ml2/db/test_ml2_dvr_db.py [deleted file]
neutron/tests/unit/plugins/openvswitch/test_ovs_dvr_neutron_agent.py [deleted file]
neutron/tests/unit/plugins/openvswitch/test_ovs_neutron_agent.py

index a3890690f0d53538afdebc4c26505c652169778b..10042e8b9b048d23d60dc5404b43fac41382f294 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import mock
+
+from sqlalchemy.orm import query
+
 from neutron import context
 from neutron.db import db_base_plugin_v2
+from neutron.db import l3_db
 from neutron.db import models_v2
 from neutron.extensions import portbindings
 from neutron.openstack.common import uuidutils
@@ -220,3 +225,137 @@ class Ml2DBTestCase(testlib_api.SqlTestCase):
                                                            port_id)
         self.assertIsNone(port)
         self.assertIsNone(binding)
+
+
+class Ml2DvrDBTestCase(testlib_api.SqlTestCase):
+
+    def setUp(self):
+        super(Ml2DvrDBTestCase, self).setUp()
+        self.ctx = context.get_admin_context()
+
+    def _setup_neutron_network(self, network_id, port_ids):
+        with self.ctx.session.begin(subtransactions=True):
+            self.ctx.session.add(models_v2.Network(id=network_id))
+            ports = []
+            for port_id in port_ids:
+                mac_address = (db_base_plugin_v2.NeutronDbPluginV2.
+                               _generate_mac())
+                port = models_v2.Port(id=port_id,
+                                      network_id=network_id,
+                                      mac_address=mac_address,
+                                      admin_state_up=True,
+                                      status='ACTIVE',
+                                      device_id='',
+                                      device_owner='')
+                self.ctx.session.add(port)
+                ports.append(port)
+            return ports
+
+    def _setup_neutron_router(self):
+        with self.ctx.session.begin(subtransactions=True):
+            router = l3_db.Router()
+            self.ctx.session.add(router)
+            return router
+
+    def _setup_dvr_binding(self, network_id, port_id, router_id, host_id):
+        with self.ctx.session.begin(subtransactions=True):
+            record = models.DVRPortBinding(
+                port_id=port_id,
+                host=host_id,
+                router_id=router_id,
+                vif_type=portbindings.VIF_TYPE_UNBOUND,
+                vnic_type=portbindings.VNIC_NORMAL,
+                status='DOWN')
+            self.ctx.session.add(record)
+            return record
+
+    def test_ensure_dvr_port_binding_deals_with_db_duplicate(self):
+        network_id = 'foo_network_id'
+        port_id = 'foo_port_id'
+        router_id = 'foo_router_id'
+        host_id = 'foo_host_id'
+        self._setup_neutron_network(network_id, [port_id])
+        self._setup_dvr_binding(network_id, port_id, router_id, host_id)
+        with mock.patch.object(query.Query, 'first') as query_first:
+            query_first.return_value = []
+            with mock.patch.object(ml2_db.LOG, 'debug') as log_trace:
+                binding = ml2_db.ensure_dvr_port_binding(
+                    self.ctx.session, port_id, host_id, router_id)
+        self.assertTrue(query_first.called)
+        self.assertTrue(log_trace.called)
+        self.assertEqual(port_id, binding.port_id)
+
+    def test_ensure_dvr_port_binding(self):
+        network_id = 'foo_network_id'
+        port_id = 'foo_port_id'
+        self._setup_neutron_network(network_id, [port_id])
+        router = self._setup_neutron_router()
+        ml2_db.ensure_dvr_port_binding(
+            self.ctx.session, port_id, 'foo_host', router.id)
+        expected = (self.ctx.session.query(models.DVRPortBinding).
+                    filter_by(port_id=port_id).one())
+        self.assertEqual(expected.port_id, port_id)
+
+    def test_ensure_dvr_port_binding_multiple_bindings(self):
+        network_id = 'foo_network_id'
+        port_id = 'foo_port_id'
+        self._setup_neutron_network(network_id, [port_id])
+        router = self._setup_neutron_router()
+        ml2_db.ensure_dvr_port_binding(
+            self.ctx.session, port_id, 'foo_host_1', router.id)
+        ml2_db.ensure_dvr_port_binding(
+            self.ctx.session, port_id, 'foo_host_2', router.id)
+        bindings = (self.ctx.session.query(models.DVRPortBinding).
+                    filter_by(port_id=port_id).all())
+        self.assertEqual(2, len(bindings))
+
+    def test_delete_dvr_port_binding(self):
+        network_id = 'foo_network_id'
+        port_id = 'foo_port_id'
+        self._setup_neutron_network(network_id, [port_id])
+        router = self._setup_neutron_router()
+        binding = self._setup_dvr_binding(
+            network_id, port_id, router.id, 'foo_host_id')
+        ml2_db.delete_dvr_port_binding(
+            self.ctx.session, port_id, 'foo_host_id')
+        count = (self.ctx.session.query(models.DVRPortBinding).
+            filter_by(port_id=binding.port_id).count())
+        self.assertFalse(count)
+
+    def test_delete_dvr_port_binding_not_found(self):
+        ml2_db.delete_dvr_port_binding(
+            self.ctx.session, 'foo_port_id', 'foo_host')
+
+    def test_delete_dvr_port_binding_if_stale(self):
+        network_id = 'foo_network_id'
+        port_id = 'foo_port_id'
+        self._setup_neutron_network(network_id, [port_id])
+        binding = self._setup_dvr_binding(
+            network_id, port_id, None, 'foo_host_id')
+
+        ml2_db.delete_dvr_port_binding_if_stale(self.ctx.session, binding)
+        count = (self.ctx.session.query(models.DVRPortBinding).
+            filter_by(port_id=binding.port_id).count())
+        self.assertFalse(count)
+
+    def test_get_dvr_port_binding_by_host_not_found(self):
+        port = ml2_db.get_dvr_port_binding_by_host(
+            self.ctx.session, 'foo_port_id', 'foo_host_id')
+        self.assertIsNone(port)
+
+    def test_get_dvr_port_bindings_not_found(self):
+        port = ml2_db.get_dvr_port_bindings(self.ctx.session, 'foo_port_id')
+        self.assertFalse(len(port))
+
+    def test_get_dvr_port_bindings(self):
+        network_id = 'foo_network_id'
+        port_id_1 = 'foo_port_id_1'
+        port_id_2 = 'foo_port_id_2'
+        self._setup_neutron_network(network_id, [port_id_1, port_id_2])
+        router = self._setup_neutron_router()
+        self._setup_dvr_binding(
+            network_id, port_id_1, router.id, 'foo_host_id_1')
+        self._setup_dvr_binding(
+            network_id, port_id_1, router.id, 'foo_host_id_2')
+        ports = ml2_db.get_dvr_port_bindings(self.ctx.session, 'foo_port_id')
+        self.assertEqual(2, len(ports))
diff --git a/neutron/tests/unit/plugins/ml2/db/test_ml2_dvr_db.py b/neutron/tests/unit/plugins/ml2/db/test_ml2_dvr_db.py
deleted file mode 100644 (file)
index 455d70d..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright (c) 2014 OpenStack Foundation, 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
-
-from sqlalchemy.orm import query
-
-from neutron import context
-from neutron.db import db_base_plugin_v2
-from neutron.db import l3_db
-from neutron.db import models_v2
-from neutron.extensions import portbindings
-from neutron.plugins.ml2 import db as ml2_db
-from neutron.plugins.ml2 import models as ml2_models
-from neutron.tests.unit import testlib_api
-
-
-class Ml2DvrDBTestCase(testlib_api.SqlTestCase):
-
-    def setUp(self):
-        super(Ml2DvrDBTestCase, self).setUp()
-        self.ctx = context.get_admin_context()
-
-    def _setup_neutron_network(self, network_id, port_ids):
-        with self.ctx.session.begin(subtransactions=True):
-            self.ctx.session.add(models_v2.Network(id=network_id))
-            ports = []
-            for port_id in port_ids:
-                mac_address = (db_base_plugin_v2.NeutronDbPluginV2.
-                               _generate_mac())
-                port = models_v2.Port(id=port_id,
-                                      network_id=network_id,
-                                      mac_address=mac_address,
-                                      admin_state_up=True,
-                                      status='ACTIVE',
-                                      device_id='',
-                                      device_owner='')
-                self.ctx.session.add(port)
-                ports.append(port)
-            return ports
-
-    def _setup_neutron_router(self):
-        with self.ctx.session.begin(subtransactions=True):
-            router = l3_db.Router()
-            self.ctx.session.add(router)
-            return router
-
-    def _setup_dvr_binding(self, network_id, port_id, router_id, host_id):
-        with self.ctx.session.begin(subtransactions=True):
-            record = ml2_models.DVRPortBinding(
-                port_id=port_id,
-                host=host_id,
-                router_id=router_id,
-                vif_type=portbindings.VIF_TYPE_UNBOUND,
-                vnic_type=portbindings.VNIC_NORMAL,
-                status='DOWN')
-            self.ctx.session.add(record)
-            return record
-
-    def test_ensure_dvr_port_binding_deals_with_db_duplicate(self):
-        network_id = 'foo_network_id'
-        port_id = 'foo_port_id'
-        router_id = 'foo_router_id'
-        host_id = 'foo_host_id'
-        self._setup_neutron_network(network_id, [port_id])
-        self._setup_dvr_binding(network_id, port_id, router_id, host_id)
-        with mock.patch.object(query.Query, 'first') as query_first:
-            query_first.return_value = []
-            with mock.patch.object(ml2_db.LOG, 'debug') as log_trace:
-                binding = ml2_db.ensure_dvr_port_binding(
-                    self.ctx.session, port_id, host_id, router_id)
-        self.assertTrue(query_first.called)
-        self.assertTrue(log_trace.called)
-        self.assertEqual(port_id, binding.port_id)
-
-    def test_ensure_dvr_port_binding(self):
-        network_id = 'foo_network_id'
-        port_id = 'foo_port_id'
-        self._setup_neutron_network(network_id, [port_id])
-        router = self._setup_neutron_router()
-        ml2_db.ensure_dvr_port_binding(
-            self.ctx.session, port_id, 'foo_host', router.id)
-        expected = (self.ctx.session.query(ml2_models.DVRPortBinding).
-                    filter_by(port_id=port_id).one())
-        self.assertEqual(expected.port_id, port_id)
-
-    def test_ensure_dvr_port_binding_multiple_bindings(self):
-        network_id = 'foo_network_id'
-        port_id = 'foo_port_id'
-        self._setup_neutron_network(network_id, [port_id])
-        router = self._setup_neutron_router()
-        ml2_db.ensure_dvr_port_binding(
-            self.ctx.session, port_id, 'foo_host_1', router.id)
-        ml2_db.ensure_dvr_port_binding(
-            self.ctx.session, port_id, 'foo_host_2', router.id)
-        bindings = (self.ctx.session.query(ml2_models.DVRPortBinding).
-                    filter_by(port_id=port_id).all())
-        self.assertEqual(2, len(bindings))
-
-    def test_delete_dvr_port_binding(self):
-        network_id = 'foo_network_id'
-        port_id = 'foo_port_id'
-        self._setup_neutron_network(network_id, [port_id])
-        router = self._setup_neutron_router()
-        binding = self._setup_dvr_binding(
-            network_id, port_id, router.id, 'foo_host_id')
-        ml2_db.delete_dvr_port_binding(
-            self.ctx.session, port_id, 'foo_host_id')
-        count = (self.ctx.session.query(ml2_models.DVRPortBinding).
-            filter_by(port_id=binding.port_id).count())
-        self.assertFalse(count)
-
-    def test_delete_dvr_port_binding_not_found(self):
-        ml2_db.delete_dvr_port_binding(
-            self.ctx.session, 'foo_port_id', 'foo_host')
-
-    def test_delete_dvr_port_binding_if_stale(self):
-        network_id = 'foo_network_id'
-        port_id = 'foo_port_id'
-        self._setup_neutron_network(network_id, [port_id])
-        binding = self._setup_dvr_binding(
-            network_id, port_id, None, 'foo_host_id')
-
-        ml2_db.delete_dvr_port_binding_if_stale(self.ctx.session, binding)
-        count = (self.ctx.session.query(ml2_models.DVRPortBinding).
-            filter_by(port_id=binding.port_id).count())
-        self.assertFalse(count)
-
-    def test_get_dvr_port_binding_by_host_not_found(self):
-        port = ml2_db.get_dvr_port_binding_by_host(
-            self.ctx.session, 'foo_port_id', 'foo_host_id')
-        self.assertIsNone(port)
-
-    def test_get_dvr_port_bindings_not_found(self):
-        port = ml2_db.get_dvr_port_bindings(self.ctx.session, 'foo_port_id')
-        self.assertFalse(len(port))
-
-    def test_get_dvr_port_bindings(self):
-        network_id = 'foo_network_id'
-        port_id_1 = 'foo_port_id_1'
-        port_id_2 = 'foo_port_id_2'
-        self._setup_neutron_network(network_id, [port_id_1, port_id_2])
-        router = self._setup_neutron_router()
-        self._setup_dvr_binding(
-            network_id, port_id_1, router.id, 'foo_host_id_1')
-        self._setup_dvr_binding(
-            network_id, port_id_1, router.id, 'foo_host_id_2')
-        ports = ml2_db.get_dvr_port_bindings(self.ctx.session, 'foo_port_id')
-        self.assertEqual(2, len(ports))
diff --git a/neutron/tests/unit/plugins/openvswitch/test_ovs_dvr_neutron_agent.py b/neutron/tests/unit/plugins/openvswitch/test_ovs_dvr_neutron_agent.py
deleted file mode 100644 (file)
index b17f44d..0000000
+++ /dev/null
@@ -1,828 +0,0 @@
-# Copyright (c) 2012 OpenStack Foundation.
-#
-#    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_config import cfg
-import oslo_messaging
-
-from neutron.agent.common import utils
-from neutron.common import constants as n_const
-from neutron.plugins.common import constants as p_const
-from neutron.plugins.openvswitch.agent import ovs_neutron_agent
-from neutron.plugins.openvswitch.common import constants
-from neutron.tests import base
-
-
-NOTIFIER = 'neutron.plugins.ml2.rpc.AgentNotifierApi'
-OVS_LINUX_KERN_VERS_WITHOUT_VXLAN = "3.12.0"
-
-FAKE_MAC = '00:11:22:33:44:55'
-FAKE_IP1 = '10.0.0.1'
-FAKE_IP2 = '10.0.0.2'
-
-
-class TestOvsDvrNeutronAgent(base.BaseTestCase):
-
-    def setUp(self):
-        super(TestOvsDvrNeutronAgent, self).setUp()
-        notifier_p = mock.patch(NOTIFIER)
-        notifier_cls = notifier_p.start()
-        self.notifier = mock.Mock()
-        notifier_cls.return_value = self.notifier
-        cfg.CONF.set_default('firewall_driver',
-                             'neutron.agent.firewall.NoopFirewallDriver',
-                             group='SECURITYGROUP')
-        kwargs = ovs_neutron_agent.create_agent_config_map(cfg.CONF)
-
-        class MockFixedIntervalLoopingCall(object):
-            def __init__(self, f):
-                self.f = f
-
-            def start(self, interval=0):
-                self.f()
-
-        with contextlib.nested(
-            mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.'
-                       'OVSNeutronAgent.setup_integration_br'),
-            mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.'
-                       'OVSNeutronAgent.setup_ancillary_bridges',
-                       return_value=[]),
-            mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                       'create'),
-            mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                       'set_secure_mode'),
-            mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                       'get_local_port_mac',
-                       return_value='00:00:00:00:00:01'),
-            mock.patch('neutron.agent.linux.utils.get_interface_mac',
-                       return_value='00:00:00:00:00:01'),
-            mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'),
-            mock.patch('neutron.openstack.common.loopingcall.'
-                       'FixedIntervalLoopingCall',
-                       new=MockFixedIntervalLoopingCall)):
-            self.agent = ovs_neutron_agent.OVSNeutronAgent(**kwargs)
-            # set back to true because initial report state will succeed due
-            # to mocked out RPC calls
-            self.agent.use_call = True
-            self.agent.tun_br = mock.Mock()
-        self.agent.sg_agent = mock.Mock()
-
-    def _setup_for_dvr_test(self, ofport=10):
-        self._port = mock.Mock()
-        self._port.ofport = ofport
-        self._port.vif_id = "1234-5678-90"
-        self._physical_network = 'physeth1'
-        self._old_local_vlan = None
-        self._segmentation_id = 2001
-        self.agent.enable_distributed_routing = True
-        self.agent.enable_tunneling = True
-        self.agent.patch_tun_ofport = 1
-        self.agent.patch_int_ofport = 2
-        self.agent.dvr_agent.local_ports = {}
-        self.agent.local_vlan_map = {}
-        self.agent.dvr_agent.enable_distributed_routing = True
-        self.agent.dvr_agent.enable_tunneling = True
-        self.agent.dvr_agent.patch_tun_ofport = 1
-        self.agent.dvr_agent.patch_int_ofport = 2
-        self.agent.dvr_agent.tun_br = mock.Mock()
-        self.agent.dvr_agent.phys_brs[self._physical_network] = mock.Mock()
-        self.agent.dvr_agent.bridge_mappings = {self._physical_network:
-                                                'br-eth1'}
-        self.agent.dvr_agent.int_ofports[self._physical_network] = 30
-        self.agent.dvr_agent.phys_ofports[self._physical_network] = 40
-        self.agent.dvr_agent.local_dvr_map = {}
-        self.agent.dvr_agent.registered_dvr_macs = set()
-        self.agent.dvr_agent.dvr_mac_address = 'aa:22:33:44:55:66'
-        self._net_uuid = 'my-net-uuid'
-        self._fixed_ips = [{'subnet_id': 'my-subnet-uuid',
-                            'ip_address': '1.1.1.1'}]
-        self._compute_port = mock.Mock()
-        self._compute_port.ofport = 20
-        self._compute_port.vif_id = "1234-5678-91"
-        self._compute_fixed_ips = [{'subnet_id': 'my-subnet-uuid',
-                                    'ip_address': '1.1.1.3'}]
-
-    def _test_port_bound_for_dvr_on_vlan_network(self, device_owner,
-                                                 ip_version=4):
-        self._setup_for_dvr_test()
-        if ip_version == 4:
-            gateway_ip = '1.1.1.1'
-            cidr = '1.1.1.0/24'
-        else:
-            gateway_ip = '2001:100::1'
-            cidr = '2001:100::0/64'
-        self._port.vif_mac = gateway_mac = 'aa:bb:cc:11:22:33'
-        self._compute_port.vif_mac = '77:88:99:00:11:22'
-        physical_network = self._physical_network
-        segmentation_id = self._segmentation_id
-        network_type = p_const.TYPE_VLAN
-        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                        'set_db_attribute',
-                        return_value=True):
-            with contextlib.nested(
-                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                           'db_get_val',
-                           return_value=self._old_local_vlan),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                                  'get_subnet_for_dvr',
-                                  return_value={
-                                      'gateway_ip': gateway_ip,
-                                      'cidr': cidr,
-                                      'ip_version': ip_version,
-                                      'gateway_mac': gateway_mac}),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                    'get_ports_on_host_by_subnet',
-                    return_value=[]),
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'get_vif_port_by_id',
-                                  return_value=self._port),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
-                mock.patch.object(
-                    self.agent.dvr_agent.phys_brs[physical_network],
-                    'add_flow'),
-                mock.patch.object(
-                    self.agent.dvr_agent.phys_brs[physical_network],
-                    'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
-                  add_flow_tun_fn, delete_flows_tun_fn, add_flow_phys_fn,
-                  delete_flows_phys_fn):
-                self.agent.port_bound(
-                    self._port, self._net_uuid, network_type,
-                    physical_network, segmentation_id, self._fixed_ips,
-                    n_const.DEVICE_OWNER_DVR_INTERFACE, False)
-                lvm = self.agent.local_vlan_map[self._net_uuid]
-                phy_ofp = self.agent.dvr_agent.phys_ofports[physical_network]
-                int_ofp = self.agent.dvr_agent.int_ofports[physical_network]
-                expected_on_phys_br = [
-                    mock.call(table=constants.LOCAL_VLAN_TRANSLATION,
-                              priority=4,
-                              in_port=phy_ofp,
-                              dl_vlan=lvm.vlan,
-                              actions="mod_vlan_vid:%s,normal" %
-                              (lvm.segmentation_id)),
-                    mock.call(table=constants.DVR_PROCESS_VLAN,
-                              priority=2,
-                              dl_vlan=lvm.vlan,
-                              dl_dst=self._port.vif_mac,
-                              actions="drop"),
-                    mock.call(table=constants.DVR_PROCESS_VLAN,
-                              priority=1,
-                              dl_vlan=lvm.vlan,
-                              dl_src=self._port.vif_mac,
-                              actions="mod_dl_src:%s,resubmit(,%s)" %
-                              (self.agent.dvr_agent.dvr_mac_address,
-                               constants.LOCAL_VLAN_TRANSLATION))
-                            ]
-                if ip_version == 4:
-                    expected_on_phys_br.insert(1, mock.call(
-                        proto='arp',
-                        nw_dst=gateway_ip, actions='drop',
-                        priority=3, table=constants.DVR_PROCESS_VLAN,
-                        dl_vlan=lvm.vlan))
-                else:
-                    expected_on_phys_br.insert(1, mock.call(
-                        icmp_type=n_const.ICMPV6_TYPE_RA, proto='icmp6',
-                        dl_src=self._port.vif_mac, actions='drop',
-                        priority=3, table=constants.DVR_PROCESS_VLAN,
-                        dl_vlan=lvm.vlan))
-                self.assertEqual(expected_on_phys_br,
-                                 add_flow_phys_fn.call_args_list)
-                self.agent.port_bound(self._compute_port, self._net_uuid,
-                                      network_type, physical_network,
-                                      segmentation_id,
-                                      self._compute_fixed_ips,
-                                      device_owner, False)
-                expected_on_int_br = [
-                    mock.call(priority=3,
-                              in_port=int_ofp,
-                              dl_vlan=lvm.segmentation_id,
-                              actions="mod_vlan_vid:%s,normal" % lvm.vlan),
-                    mock.call(table=constants.DVR_TO_SRC_MAC_VLAN,
-                              priority=4,
-                              dl_dst=self._compute_port.vif_mac,
-                              dl_vlan=lvm.segmentation_id,
-                              actions="strip_vlan,mod_dl_src:%s,"
-                              "output:%s" %
-                              (gateway_mac,
-                               self._compute_port.ofport))
-                                      ]
-                self.assertEqual(expected_on_int_br,
-                                 add_flow_int_fn.call_args_list)
-                expected_on_int_br = [
-                    mock.call(in_port=self._port.ofport),
-                    mock.call(in_port=self._compute_port.ofport)
-                                      ]
-                self.assertEqual(expected_on_int_br,
-                                 delete_flows_int_fn.call_args_list)
-                self.assertFalse(add_flow_tun_fn.called)
-                self.assertFalse(delete_flows_tun_fn.called)
-                self.assertFalse(delete_flows_phys_fn.called)
-
-    def _test_port_bound_for_dvr_on_vxlan_network(self, device_owner,
-                                                  ip_version=4):
-        self._setup_for_dvr_test()
-        if ip_version == 4:
-            gateway_ip = '1.1.1.1'
-            cidr = '1.1.1.0/24'
-        else:
-            gateway_ip = '2001:100::1'
-            cidr = '2001:100::0/64'
-        network_type = p_const.TYPE_VXLAN
-        self._port.vif_mac = gateway_mac = 'aa:bb:cc:11:22:33'
-        self._compute_port.vif_mac = '77:88:99:00:11:22'
-        physical_network = self._physical_network
-        segmentation_id = self._segmentation_id
-        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                        'set_db_attribute',
-                        return_value=True):
-            with contextlib.nested(
-                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                           'db_get_val',
-                           return_value=self._old_local_vlan),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                                  'get_subnet_for_dvr',
-                                  return_value={
-                                      'gateway_ip': gateway_ip,
-                                      'cidr': cidr,
-                                      'ip_version': ip_version,
-                                      'gateway_mac': gateway_mac}),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                    'get_ports_on_host_by_subnet',
-                    return_value=[]),
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'get_vif_port_by_id',
-                                  return_value=self._port),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
-                mock.patch.object(
-                    self.agent.dvr_agent.phys_brs[physical_network],
-                    'add_flow'),
-                mock.patch.object(
-                    self.agent.dvr_agent.phys_brs[physical_network],
-                    'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
-                  add_flow_tun_fn, delete_flows_tun_fn,
-                  add_flow_phys_fn, delete_flows_phys_fn):
-                self.agent.port_bound(
-                    self._port, self._net_uuid, network_type,
-                    physical_network, segmentation_id, self._fixed_ips,
-                    n_const.DEVICE_OWNER_DVR_INTERFACE, False)
-                lvm = self.agent.local_vlan_map[self._net_uuid]
-                expected_on_tun_br = [
-                    mock.call(
-                        table=constants.TUN_TABLE['vxlan'],
-                        priority=1, tun_id=lvm.segmentation_id,
-                        actions="mod_vlan_vid:%s,"
-                        "resubmit(,%s)" %
-                        (lvm.vlan, constants.DVR_NOT_LEARN)),
-                    mock.call(
-                        table=constants.DVR_PROCESS, priority=2,
-                        dl_vlan=lvm.vlan,
-                        dl_dst=self._port.vif_mac,
-                        actions='drop'),
-                    mock.call(
-                        table=constants.DVR_PROCESS, priority=1,
-                        dl_vlan=lvm.vlan,
-                        dl_src=self._port.vif_mac,
-                        actions="mod_dl_src:%s,resubmit(,%s)" % (
-                            self.agent.dvr_agent.dvr_mac_address,
-                            constants.PATCH_LV_TO_TUN))]
-                if ip_version == 4:
-                    expected_on_tun_br.insert(1, mock.call(
-                        proto='arp',
-                        nw_dst=gateway_ip, actions='drop',
-                        priority=3, table=constants.DVR_PROCESS,
-                        dl_vlan=lvm.vlan))
-                else:
-                    expected_on_tun_br.insert(1, mock.call(
-                        icmp_type=n_const.ICMPV6_TYPE_RA,
-                        proto='icmp6',
-                        dl_src=self._port.vif_mac,
-                        actions='drop',
-                        priority=3, table=constants.DVR_PROCESS,
-                        dl_vlan=lvm.vlan))
-                self.assertEqual(expected_on_tun_br,
-                                 add_flow_tun_fn.call_args_list)
-                self.agent.port_bound(self._compute_port, self._net_uuid,
-                                      network_type, physical_network,
-                                      segmentation_id,
-                                      self._compute_fixed_ips,
-                                      device_owner, False)
-                expected_on_int_br = [
-                    mock.call(table=constants.DVR_TO_SRC_MAC, priority=4,
-                        dl_dst=self._compute_port.vif_mac,
-                        dl_vlan=lvm.vlan,
-                        actions="strip_vlan,mod_dl_src:%s,"
-                        "output:%s" %
-                        (gateway_mac, self._compute_port.ofport))
-                                ]
-                self.assertEqual(expected_on_int_br,
-                                 add_flow_int_fn.call_args_list)
-                self.assertFalse(add_flow_phys_fn.called)
-                expected_on_int_br = [
-                    mock.call(in_port=self._port.ofport),
-                    mock.call(in_port=self._compute_port.ofport)
-                                      ]
-                self.assertEqual(expected_on_int_br,
-                                 delete_flows_int_fn.call_args_list)
-                self.assertFalse(add_flow_phys_fn.called)
-                self.assertFalse(delete_flows_tun_fn.called)
-                self.assertFalse(delete_flows_phys_fn.called)
-
-    def test_port_bound_for_dvr_with_compute_ports(self):
-        self._test_port_bound_for_dvr_on_vlan_network(
-            device_owner="compute:None")
-        self._test_port_bound_for_dvr_on_vlan_network(
-            device_owner="compute:None", ip_version=6)
-        self._test_port_bound_for_dvr_on_vxlan_network(
-            device_owner="compute:None")
-        self._test_port_bound_for_dvr_on_vxlan_network(
-            device_owner="compute:None", ip_version=6)
-
-    def test_port_bound_for_dvr_with_lbaas_vip_ports(self):
-        self._test_port_bound_for_dvr_on_vlan_network(
-            device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
-        self._test_port_bound_for_dvr_on_vlan_network(
-            device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
-        self._test_port_bound_for_dvr_on_vxlan_network(
-            device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
-        self._test_port_bound_for_dvr_on_vxlan_network(
-            device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
-
-    def test_port_bound_for_dvr_with_dhcp_ports(self):
-        self._test_port_bound_for_dvr_on_vlan_network(
-            device_owner=n_const.DEVICE_OWNER_DHCP)
-        self._test_port_bound_for_dvr_on_vlan_network(
-            device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
-        self._test_port_bound_for_dvr_on_vxlan_network(
-            device_owner=n_const.DEVICE_OWNER_DHCP)
-        self._test_port_bound_for_dvr_on_vxlan_network(
-            device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
-
-    def test_port_bound_for_dvr_with_csnat_ports(self, ofport=10):
-        self._setup_for_dvr_test()
-        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                        'set_db_attribute',
-                        return_value=True):
-            with contextlib.nested(
-                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                           'db_get_val',
-                           return_value=self._old_local_vlan),
-                mock.patch.object(
-                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
-                    return_value={'gateway_ip': '1.1.1.1',
-                                  'cidr': '1.1.1.0/24',
-                                  'ip_version': 4,
-                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                    'get_ports_on_host_by_subnet',
-                    return_value=[]),
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'get_vif_port_by_id',
-                                  return_value=self._port),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
-                  add_flow_tun_fn, delete_flows_tun_fn):
-                self.agent.port_bound(
-                    self._port, self._net_uuid, 'vxlan',
-                    None, None, self._fixed_ips,
-                    n_const.DEVICE_OWNER_ROUTER_SNAT,
-                    False)
-                self.assertTrue(add_flow_int_fn.called)
-                self.assertTrue(delete_flows_int_fn.called)
-
-    def test_treat_devices_removed_for_dvr_interface(self, ofport=10):
-        self._test_treat_devices_removed_for_dvr_interface(ofport)
-        self._test_treat_devices_removed_for_dvr_interface(
-            ofport, ip_version=6)
-
-    def _test_treat_devices_removed_for_dvr_interface(self, ofport=10,
-                                                      ip_version=4):
-        self._setup_for_dvr_test()
-        if ip_version == 4:
-            gateway_ip = '1.1.1.1'
-            cidr = '1.1.1.0/24'
-        else:
-            gateway_ip = '2001:100::1'
-            cidr = '2001:100::0/64'
-        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                        'set_db_attribute',
-                        return_value=True):
-            with contextlib.nested(
-                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                           'db_get_val',
-                           return_value=self._old_local_vlan),
-                mock.patch.object(
-                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
-                    return_value={'gateway_ip': gateway_ip,
-                                  'cidr': cidr,
-                                  'ip_version': ip_version,
-                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                    'get_ports_on_host_by_subnet',
-                    return_value=[]),
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'get_vif_port_by_id',
-                                  return_value=self._port),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
-                  add_flow_tun_fn, delete_flows_tun_fn):
-                self.agent.port_bound(
-                    self._port, self._net_uuid, 'vxlan',
-                    None, None, self._fixed_ips,
-                    n_const.DEVICE_OWNER_DVR_INTERFACE,
-                    False)
-                self.assertTrue(add_flow_tun_fn.called)
-                self.assertTrue(delete_flows_int_fn.called)
-
-        with contextlib.nested(
-            mock.patch.object(self.agent, 'reclaim_local_vlan'),
-            mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
-                              return_value=None),
-            mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-            mock.patch.object(self.agent.dvr_agent.tun_br,
-                              'delete_flows')) as (reclaim_vlan_fn,
-                                                   update_dev_down_fn,
-                                                   delete_flows_int_fn,
-                                                   delete_flows_tun_fn):
-                self.agent.treat_devices_removed([self._port.vif_id])
-                if ip_version == 4:
-                    expected = [mock.call(
-                        proto='arp',
-                        nw_dst=gateway_ip,
-                        table=constants.DVR_PROCESS,
-                        dl_vlan=(
-                            self.agent.local_vlan_map[self._net_uuid].vlan))]
-                else:
-                    expected = [mock.call(
-                        icmp_type=n_const.ICMPV6_TYPE_RA, proto='icmp6',
-                        dl_src='aa:bb:cc:11:22:33',
-                        table=constants.DVR_PROCESS,
-                        dl_vlan=(
-                            self.agent.local_vlan_map[self._net_uuid].vlan))]
-                expected.extend([
-                    mock.call(
-                        table=constants.DVR_PROCESS,
-                        dl_dst=self._port.vif_mac,
-                        dl_vlan=(
-                            self.agent.local_vlan_map[self._net_uuid].vlan)),
-                    mock.call(
-                        table=constants.DVR_PROCESS,
-                        dl_vlan=(
-                            self.agent.local_vlan_map[self._net_uuid].vlan),
-                        dl_src=self._port.vif_mac)
-                ])
-                self.assertEqual(expected, delete_flows_tun_fn.call_args_list)
-
-    def _test_treat_devices_removed_for_dvr(self, device_owner, ip_version=4):
-        self._setup_for_dvr_test()
-        if ip_version == 4:
-            gateway_ip = '1.1.1.1'
-            cidr = '1.1.1.0/24'
-        else:
-            gateway_ip = '2001:100::1'
-            cidr = '2001:100::0/64'
-        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                        'set_db_attribute',
-                        return_value=True):
-            with contextlib.nested(
-                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                           'db_get_val',
-                           return_value=self._old_local_vlan),
-                mock.patch.object(
-                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
-                    return_value={'gateway_ip': gateway_ip,
-                                  'cidr': cidr,
-                                  'ip_version': ip_version,
-                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                    'get_ports_on_host_by_subnet',
-                    return_value=[]),
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'get_vif_port_by_id',
-                                  return_value=self._port),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
-                  add_flow_tun_fn, delete_flows_tun_fn):
-                self.agent.port_bound(
-                    self._port, self._net_uuid, 'vxlan',
-                    None, None, self._fixed_ips,
-                    n_const.DEVICE_OWNER_DVR_INTERFACE,
-                    False)
-                self.agent.port_bound(self._compute_port,
-                                      self._net_uuid, 'vxlan',
-                                      None, None,
-                                      self._compute_fixed_ips,
-                                      device_owner, False)
-                self.assertTrue(add_flow_tun_fn.called)
-                self.assertTrue(add_flow_int_fn.called)
-                self.assertTrue(delete_flows_int_fn.called)
-
-        with contextlib.nested(
-            mock.patch.object(self.agent, 'reclaim_local_vlan'),
-            mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
-                              return_value=None),
-            mock.patch.object(self.agent.dvr_agent.int_br,
-                              'delete_flows')) as (reclaim_vlan_fn,
-                                                   update_dev_down_fn,
-                                                   delete_flows_int_fn):
-                self.agent.treat_devices_removed([self._compute_port.vif_id])
-                expected = [
-                    mock.call(
-                        table=constants.DVR_TO_SRC_MAC,
-                        dl_dst=self._compute_port.vif_mac,
-                        dl_vlan=(
-                            self.agent.local_vlan_map[self._net_uuid].vlan))]
-                self.assertEqual(expected, delete_flows_int_fn.call_args_list)
-
-    def test_treat_devices_removed_for_dvr_with_compute_ports(self):
-        self._test_treat_devices_removed_for_dvr(
-            device_owner="compute:None")
-        self._test_treat_devices_removed_for_dvr(
-            device_owner="compute:None", ip_version=6)
-
-    def test_treat_devices_removed_for_dvr_with_lbaas_vip_ports(self):
-        self._test_treat_devices_removed_for_dvr(
-            device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
-        self._test_treat_devices_removed_for_dvr(
-            device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
-
-    def test_treat_devices_removed_for_dvr_with_dhcp_ports(self):
-        self._test_treat_devices_removed_for_dvr(
-            device_owner=n_const.DEVICE_OWNER_DHCP)
-        self._test_treat_devices_removed_for_dvr(
-            device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
-
-    def test_treat_devices_removed_for_dvr_csnat_port(self, ofport=10):
-        self._setup_for_dvr_test()
-        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                        'set_db_attribute',
-                        return_value=True):
-            with contextlib.nested(
-                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
-                           'db_get_val',
-                           return_value=self._old_local_vlan),
-                mock.patch.object(
-                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
-                    return_value={'gateway_ip': '1.1.1.1',
-                                  'cidr': '1.1.1.0/24',
-                                  'ip_version': 4,
-                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                    'get_ports_on_host_by_subnet',
-                    return_value=[]),
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'get_vif_port_by_id',
-                                  return_value=self._port),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
-            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
-                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
-                  add_flow_tun_fn, delete_flows_tun_fn):
-                self.agent.port_bound(
-                    self._port, self._net_uuid, 'vxlan',
-                    None, None, self._fixed_ips,
-                    n_const.DEVICE_OWNER_ROUTER_SNAT,
-                    False)
-                self.assertTrue(add_flow_int_fn.called)
-                self.assertTrue(delete_flows_int_fn.called)
-
-        with contextlib.nested(
-            mock.patch.object(self.agent, 'reclaim_local_vlan'),
-            mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
-                              return_value=None),
-            mock.patch.object(self.agent.dvr_agent.int_br,
-                              'delete_flows')) as (reclaim_vlan_fn,
-                                                   update_dev_down_fn,
-                                                   delete_flows_int_fn):
-                self.agent.treat_devices_removed([self._port.vif_id])
-                self.assertTrue(delete_flows_int_fn.called)
-
-    def test_setup_dvr_flows_on_int_br(self):
-        self._setup_for_dvr_test()
-        with contextlib.nested(
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'remove_all_flows'),
-                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-                mock.patch.object(
-                    self.agent.dvr_agent.plugin_rpc,
-                    'get_dvr_mac_address_list',
-                    return_value=[{'host': 'cn1',
-                                   'mac_address': 'aa:bb:cc:dd:ee:ff'},
-                                  {'host': 'cn2',
-                                   'mac_address': '11:22:33:44:55:66'}])) as \
-            (remove_flows_fn, add_int_flow_fn, add_tun_flow_fn,
-             get_mac_list_fn):
-            self.agent.dvr_agent.setup_dvr_flows_on_integ_br()
-            self.assertTrue(self.agent.dvr_agent.in_distributed_mode())
-            physical_networks = self.agent.dvr_agent.bridge_mappings.keys()
-            ioport = self.agent.dvr_agent.int_ofports[physical_networks[0]]
-            expected = [
-                    mock.call(table=constants.CANARY_TABLE,
-                              priority=0,
-                              actions="drop"),
-                    mock.call(table=constants.DVR_TO_SRC_MAC,
-                             priority=1,
-                             actions="drop"),
-                    mock.call(table=constants.DVR_TO_SRC_MAC_VLAN,
-                             priority=1,
-                             actions="drop"),
-                    mock.call(table=constants.LOCAL_SWITCHING,
-                             priority=1,
-                             actions="normal"),
-                    mock.call(
-                        table=constants.LOCAL_SWITCHING, priority=2,
-                        actions="drop",
-                        in_port=ioport)]
-            self.assertTrue(remove_flows_fn.called)
-            self.assertEqual(expected, add_int_flow_fn.call_args_list)
-            self.assertEqual(add_int_flow_fn.call_count, 5)
-
-    def test_get_dvr_mac_address(self):
-        self._setup_for_dvr_test()
-        self.agent.dvr_agent.dvr_mac_address = None
-        with mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                               'get_dvr_mac_address_by_host',
-                               return_value={'host': 'cn1',
-                                  'mac_address': 'aa:22:33:44:55:66'}):
-            self.agent.dvr_agent.get_dvr_mac_address()
-            self.assertEqual('aa:22:33:44:55:66',
-                             self.agent.dvr_agent.dvr_mac_address)
-            self.assertTrue(self.agent.dvr_agent.in_distributed_mode())
-
-    def test_get_dvr_mac_address_exception(self):
-        self._setup_for_dvr_test()
-        self.agent.dvr_agent.dvr_mac_address = None
-        with contextlib.nested(
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                               'get_dvr_mac_address_by_host',
-                               side_effect=oslo_messaging.RemoteError),
-                mock.patch.object(self.agent.dvr_agent.int_br,
-                                  'add_flow')) as (gd_mac, add_int_flow_fn):
-
-            self.agent.dvr_agent.get_dvr_mac_address()
-            self.assertIsNone(self.agent.dvr_agent.dvr_mac_address)
-            self.assertFalse(self.agent.dvr_agent.in_distributed_mode())
-            self.assertEqual(add_int_flow_fn.call_count, 1)
-
-    def test_get_dvr_mac_address_retried(self):
-        valid_entry = {'host': 'cn1', 'mac_address': 'aa:22:33:44:55:66'}
-        raise_timeout = oslo_messaging.MessagingTimeout()
-        # Raise a timeout the first 2 times it calls get_dvr_mac_address()
-        self._setup_for_dvr_test()
-        self.agent.dvr_agent.dvr_mac_address = None
-        with mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                               'get_dvr_mac_address_by_host',
-                               side_effect=(raise_timeout, raise_timeout,
-                                            valid_entry)):
-            self.agent.dvr_agent.get_dvr_mac_address()
-            self.assertEqual('aa:22:33:44:55:66',
-                             self.agent.dvr_agent.dvr_mac_address)
-            self.assertTrue(self.agent.dvr_agent.in_distributed_mode())
-            self.assertEqual(self.agent.dvr_agent.plugin_rpc.
-                             get_dvr_mac_address_by_host.call_count, 3)
-
-    def test_get_dvr_mac_address_retried_max(self):
-        raise_timeout = oslo_messaging.MessagingTimeout()
-        # Raise a timeout every time until we give up, currently 5 tries
-        self._setup_for_dvr_test()
-        self.agent.dvr_agent.dvr_mac_address = None
-        with contextlib.nested(
-                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
-                                 'get_dvr_mac_address_by_host',
-                                 side_effect=raise_timeout),
-                mock.patch.object(utils, "execute"),
-        ) as (rpc_mock, execute_mock):
-            self.agent.dvr_agent.get_dvr_mac_address()
-            self.assertIsNone(self.agent.dvr_agent.dvr_mac_address)
-            self.assertFalse(self.agent.dvr_agent.in_distributed_mode())
-            self.assertEqual(self.agent.dvr_agent.plugin_rpc.
-                             get_dvr_mac_address_by_host.call_count, 5)
-
-    def test_dvr_mac_address_update(self):
-        self._setup_for_dvr_test()
-        newhost = 'cn2'
-        newmac = 'aa:bb:cc:dd:ee:ff'
-        int_ofport = self.agent.dvr_agent.int_ofports['physeth1']
-        patch_int_ofport = self.agent.dvr_agent.patch_int_ofport
-        patch_tun_ofport = self.agent.dvr_agent.patch_tun_ofport
-        with contextlib.nested(
-            mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-            mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
-            mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-            mock.patch.object(self.agent.dvr_agent.phys_brs['physeth1'],
-                              'add_flow')
-        ) as (add_flow_fn, add_flow_tn_fn, del_flows_fn, add_flow_phys_fn):
-            self.agent.dvr_agent.\
-                dvr_mac_address_update(
-                    dvr_macs=[{'host': newhost,
-                               'mac_address': newmac}])
-            expected = [
-                    mock.call(table=constants.LOCAL_SWITCHING,
-                              priority=4,
-                              in_port=int_ofport,
-                              dl_src=newmac,
-                              actions="resubmit(,%s)" %
-                              constants.DVR_TO_SRC_MAC_VLAN),
-                    mock.call(table=constants.LOCAL_SWITCHING,
-                              priority=2,
-                              in_port=patch_tun_ofport,
-                              dl_src=newmac,
-                              actions="resubmit(,%s)" %
-                              constants.DVR_TO_SRC_MAC)]
-            self.assertEqual(expected, add_flow_fn.call_args_list)
-            add_flow_phys_fn.assert_called_with(
-                    table=constants.DVR_NOT_LEARN_VLAN,
-                    priority=2,
-                    dl_src=newmac,
-                    actions="output:%s" %
-                    self.agent.dvr_agent.phys_ofports['physeth1'])
-            add_flow_tn_fn.assert_called_with(table=constants.DVR_NOT_LEARN,
-                                              priority=1,
-                                              dl_src=newmac,
-                                              actions="output:%s"
-                                              % patch_int_ofport)
-            self.assertFalse(del_flows_fn.called)
-        with contextlib.nested(
-            mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
-            mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
-            mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
-            mock.patch.object(self.agent.dvr_agent.phys_brs['physeth1'],
-                              'delete_flows'),
-        ) as (add_flow_fn, del_flows_tn_fn, del_flows_fn, del_flows_phys_fn):
-            self.agent.dvr_agent.dvr_mac_address_update(dvr_macs=[])
-            ioport = self.agent.dvr_agent.int_ofports['physeth1']
-            expected = [
-                 mock.call(table=constants.LOCAL_SWITCHING,
-                           in_port=ioport,
-                           dl_src=newmac),
-                 mock.call(table=constants.LOCAL_SWITCHING,
-                           in_port=patch_tun_ofport,
-                           dl_src=newmac)]
-            self.assertEqual(expected, del_flows_fn.call_args_list)
-            del_flows_phys_fn.asert_called_with(
-                    table=constants.DVR_NOT_LEARN_VLAN,
-                    dl_src=newmac)
-            del_flows_tn_fn.assert_called_with(table=constants.DVR_NOT_LEARN,
-                                               dl_src=newmac)
-            self.assertFalse(add_flow_fn.called)
-
-    def test_ovs_restart(self):
-        self._setup_for_dvr_test()
-        reset_methods = (
-            'reset_ovs_parameters', 'reset_dvr_parameters',
-            'setup_dvr_flows_on_integ_br', 'setup_dvr_flows_on_tun_br',
-            'setup_dvr_flows_on_phys_br', 'setup_dvr_mac_flows_on_all_brs')
-        reset_mocks = [mock.patch.object(self.agent.dvr_agent, method).start()
-                       for method in reset_methods]
-        with contextlib.nested(
-            mock.patch.object(self.agent, 'check_ovs_status',
-                              return_value=constants.OVS_RESTARTED),
-            mock.patch.object(self.agent, '_agent_has_updates',
-                              side_effect=TypeError('loop exit'))
-        ):
-            # block RPC calls and bridge calls
-            self.agent.setup_physical_bridges = mock.Mock()
-            self.agent.setup_integration_br = mock.Mock()
-            self.agent.reset_tunnel_br = mock.Mock()
-            self.agent.state_rpc = mock.Mock()
-            try:
-                self.agent.rpc_loop(polling_manager=mock.Mock())
-            except TypeError:
-                pass
-        self.assertTrue(all([x.called for x in reset_mocks]))
index 58f2769ac69d66b2fbbe804b6f70e74fc11cedd2..f39ecd0ce79b4c896fbfccd2761c4c1819f37e26 100644 (file)
@@ -20,6 +20,7 @@ import mock
 import netaddr
 from oslo_config import cfg
 from oslo_log import log
+import oslo_messaging
 import testtools
 
 from neutron.agent.common import ovs_lib
@@ -1157,3 +1158,797 @@ class AncillaryBridgesTest(base.BaseTestCase):
     def test_ancillary_bridges_multiple(self):
         bridges = ['br-int', 'br-ex1', 'br-ex2']
         self._test_ancillary_bridges(bridges, ['br-ex1', 'br-ex2'])
+
+
+class TestOvsDvrNeutronAgent(base.BaseTestCase):
+
+    def setUp(self):
+        super(TestOvsDvrNeutronAgent, self).setUp()
+        notifier_p = mock.patch(NOTIFIER)
+        notifier_cls = notifier_p.start()
+        self.notifier = mock.Mock()
+        notifier_cls.return_value = self.notifier
+        cfg.CONF.set_default('firewall_driver',
+                             'neutron.agent.firewall.NoopFirewallDriver',
+                             group='SECURITYGROUP')
+        kwargs = ovs_neutron_agent.create_agent_config_map(cfg.CONF)
+
+        class MockFixedIntervalLoopingCall(object):
+            def __init__(self, f):
+                self.f = f
+
+            def start(self, interval=0):
+                self.f()
+
+        with contextlib.nested(
+            mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.'
+                       'OVSNeutronAgent.setup_integration_br'),
+            mock.patch('neutron.plugins.openvswitch.agent.ovs_neutron_agent.'
+                       'OVSNeutronAgent.setup_ancillary_bridges',
+                       return_value=[]),
+            mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                       'create'),
+            mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                       'set_secure_mode'),
+            mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                       'get_local_port_mac',
+                       return_value='00:00:00:00:00:01'),
+            mock.patch('neutron.agent.linux.utils.get_interface_mac',
+                       return_value='00:00:00:00:00:01'),
+            mock.patch('neutron.agent.common.ovs_lib.BaseOVS.get_bridges'),
+            mock.patch('neutron.openstack.common.loopingcall.'
+                       'FixedIntervalLoopingCall',
+                       new=MockFixedIntervalLoopingCall)):
+            self.agent = ovs_neutron_agent.OVSNeutronAgent(**kwargs)
+            # set back to true because initial report state will succeed due
+            # to mocked out RPC calls
+            self.agent.use_call = True
+            self.agent.tun_br = mock.Mock()
+        self.agent.sg_agent = mock.Mock()
+
+    def _setup_for_dvr_test(self, ofport=10):
+        self._port = mock.Mock()
+        self._port.ofport = ofport
+        self._port.vif_id = "1234-5678-90"
+        self._physical_network = 'physeth1'
+        self._old_local_vlan = None
+        self._segmentation_id = 2001
+        self.agent.enable_distributed_routing = True
+        self.agent.enable_tunneling = True
+        self.agent.patch_tun_ofport = 1
+        self.agent.patch_int_ofport = 2
+        self.agent.dvr_agent.local_ports = {}
+        self.agent.local_vlan_map = {}
+        self.agent.dvr_agent.enable_distributed_routing = True
+        self.agent.dvr_agent.enable_tunneling = True
+        self.agent.dvr_agent.patch_tun_ofport = 1
+        self.agent.dvr_agent.patch_int_ofport = 2
+        self.agent.dvr_agent.tun_br = mock.Mock()
+        self.agent.dvr_agent.phys_brs[self._physical_network] = mock.Mock()
+        self.agent.dvr_agent.bridge_mappings = {self._physical_network:
+                                                'br-eth1'}
+        self.agent.dvr_agent.int_ofports[self._physical_network] = 30
+        self.agent.dvr_agent.phys_ofports[self._physical_network] = 40
+        self.agent.dvr_agent.local_dvr_map = {}
+        self.agent.dvr_agent.registered_dvr_macs = set()
+        self.agent.dvr_agent.dvr_mac_address = 'aa:22:33:44:55:66'
+        self._net_uuid = 'my-net-uuid'
+        self._fixed_ips = [{'subnet_id': 'my-subnet-uuid',
+                            'ip_address': '1.1.1.1'}]
+        self._compute_port = mock.Mock()
+        self._compute_port.ofport = 20
+        self._compute_port.vif_id = "1234-5678-91"
+        self._compute_fixed_ips = [{'subnet_id': 'my-subnet-uuid',
+                                    'ip_address': '1.1.1.3'}]
+
+    def _test_port_bound_for_dvr_on_vlan_network(self, device_owner,
+                                                 ip_version=4):
+        self._setup_for_dvr_test()
+        if ip_version == 4:
+            gateway_ip = '1.1.1.1'
+            cidr = '1.1.1.0/24'
+        else:
+            gateway_ip = '2001:100::1'
+            cidr = '2001:100::0/64'
+        self._port.vif_mac = gateway_mac = 'aa:bb:cc:11:22:33'
+        self._compute_port.vif_mac = '77:88:99:00:11:22'
+        physical_network = self._physical_network
+        segmentation_id = self._segmentation_id
+        network_type = p_const.TYPE_VLAN
+        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                        'set_db_attribute',
+                        return_value=True):
+            with contextlib.nested(
+                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                           'db_get_val',
+                           return_value=self._old_local_vlan),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                                  'get_subnet_for_dvr',
+                                  return_value={
+                                      'gateway_ip': gateway_ip,
+                                      'cidr': cidr,
+                                      'ip_version': ip_version,
+                                      'gateway_mac': gateway_mac}),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                    'get_ports_on_host_by_subnet',
+                    return_value=[]),
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'get_vif_port_by_id',
+                                  return_value=self._port),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
+                mock.patch.object(
+                    self.agent.dvr_agent.phys_brs[physical_network],
+                    'add_flow'),
+                mock.patch.object(
+                    self.agent.dvr_agent.phys_brs[physical_network],
+                    'delete_flows')
+            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+                  add_flow_tun_fn, delete_flows_tun_fn, add_flow_phys_fn,
+                  delete_flows_phys_fn):
+                self.agent.port_bound(
+                    self._port, self._net_uuid, network_type,
+                    physical_network, segmentation_id, self._fixed_ips,
+                    n_const.DEVICE_OWNER_DVR_INTERFACE, False)
+                lvm = self.agent.local_vlan_map[self._net_uuid]
+                phy_ofp = self.agent.dvr_agent.phys_ofports[physical_network]
+                int_ofp = self.agent.dvr_agent.int_ofports[physical_network]
+                expected_on_phys_br = [
+                    mock.call(table=constants.LOCAL_VLAN_TRANSLATION,
+                              priority=4,
+                              in_port=phy_ofp,
+                              dl_vlan=lvm.vlan,
+                              actions="mod_vlan_vid:%s,normal" %
+                              (lvm.segmentation_id)),
+                    mock.call(table=constants.DVR_PROCESS_VLAN,
+                              priority=2,
+                              dl_vlan=lvm.vlan,
+                              dl_dst=self._port.vif_mac,
+                              actions="drop"),
+                    mock.call(table=constants.DVR_PROCESS_VLAN,
+                              priority=1,
+                              dl_vlan=lvm.vlan,
+                              dl_src=self._port.vif_mac,
+                              actions="mod_dl_src:%s,resubmit(,%s)" %
+                              (self.agent.dvr_agent.dvr_mac_address,
+                               constants.LOCAL_VLAN_TRANSLATION))
+                            ]
+                if ip_version == 4:
+                    expected_on_phys_br.insert(1, mock.call(
+                        proto='arp',
+                        nw_dst=gateway_ip, actions='drop',
+                        priority=3, table=constants.DVR_PROCESS_VLAN,
+                        dl_vlan=lvm.vlan))
+                else:
+                    expected_on_phys_br.insert(1, mock.call(
+                        icmp_type=n_const.ICMPV6_TYPE_RA, proto='icmp6',
+                        dl_src=self._port.vif_mac, actions='drop',
+                        priority=3, table=constants.DVR_PROCESS_VLAN,
+                        dl_vlan=lvm.vlan))
+                self.assertEqual(expected_on_phys_br,
+                                 add_flow_phys_fn.call_args_list)
+                self.agent.port_bound(self._compute_port, self._net_uuid,
+                                      network_type, physical_network,
+                                      segmentation_id,
+                                      self._compute_fixed_ips,
+                                      device_owner, False)
+                expected_on_int_br = [
+                    mock.call(priority=3,
+                              in_port=int_ofp,
+                              dl_vlan=lvm.segmentation_id,
+                              actions="mod_vlan_vid:%s,normal" % lvm.vlan),
+                    mock.call(table=constants.DVR_TO_SRC_MAC_VLAN,
+                              priority=4,
+                              dl_dst=self._compute_port.vif_mac,
+                              dl_vlan=lvm.segmentation_id,
+                              actions="strip_vlan,mod_dl_src:%s,"
+                              "output:%s" %
+                              (gateway_mac,
+                               self._compute_port.ofport))
+                                      ]
+                self.assertEqual(expected_on_int_br,
+                                 add_flow_int_fn.call_args_list)
+                expected_on_int_br = [
+                    mock.call(in_port=self._port.ofport),
+                    mock.call(in_port=self._compute_port.ofport)
+                                      ]
+                self.assertEqual(expected_on_int_br,
+                                 delete_flows_int_fn.call_args_list)
+                self.assertFalse(add_flow_tun_fn.called)
+                self.assertFalse(delete_flows_tun_fn.called)
+                self.assertFalse(delete_flows_phys_fn.called)
+
+    def _test_port_bound_for_dvr_on_vxlan_network(self, device_owner,
+                                                  ip_version=4):
+        self._setup_for_dvr_test()
+        if ip_version == 4:
+            gateway_ip = '1.1.1.1'
+            cidr = '1.1.1.0/24'
+        else:
+            gateway_ip = '2001:100::1'
+            cidr = '2001:100::0/64'
+        network_type = p_const.TYPE_VXLAN
+        self._port.vif_mac = gateway_mac = 'aa:bb:cc:11:22:33'
+        self._compute_port.vif_mac = '77:88:99:00:11:22'
+        physical_network = self._physical_network
+        segmentation_id = self._segmentation_id
+        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                        'set_db_attribute',
+                        return_value=True):
+            with contextlib.nested(
+                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                           'db_get_val',
+                           return_value=self._old_local_vlan),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                                  'get_subnet_for_dvr',
+                                  return_value={
+                                      'gateway_ip': gateway_ip,
+                                      'cidr': cidr,
+                                      'ip_version': ip_version,
+                                      'gateway_mac': gateway_mac}),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                    'get_ports_on_host_by_subnet',
+                    return_value=[]),
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'get_vif_port_by_id',
+                                  return_value=self._port),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
+                mock.patch.object(
+                    self.agent.dvr_agent.phys_brs[physical_network],
+                    'add_flow'),
+                mock.patch.object(
+                    self.agent.dvr_agent.phys_brs[physical_network],
+                    'delete_flows')
+            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+                  add_flow_tun_fn, delete_flows_tun_fn,
+                  add_flow_phys_fn, delete_flows_phys_fn):
+                self.agent.port_bound(
+                    self._port, self._net_uuid, network_type,
+                    physical_network, segmentation_id, self._fixed_ips,
+                    n_const.DEVICE_OWNER_DVR_INTERFACE, False)
+                lvm = self.agent.local_vlan_map[self._net_uuid]
+                expected_on_tun_br = [
+                    mock.call(
+                        table=constants.TUN_TABLE['vxlan'],
+                        priority=1, tun_id=lvm.segmentation_id,
+                        actions="mod_vlan_vid:%s,"
+                        "resubmit(,%s)" %
+                        (lvm.vlan, constants.DVR_NOT_LEARN)),
+                    mock.call(
+                        table=constants.DVR_PROCESS, priority=2,
+                        dl_vlan=lvm.vlan,
+                        dl_dst=self._port.vif_mac,
+                        actions='drop'),
+                    mock.call(
+                        table=constants.DVR_PROCESS, priority=1,
+                        dl_vlan=lvm.vlan,
+                        dl_src=self._port.vif_mac,
+                        actions="mod_dl_src:%s,resubmit(,%s)" % (
+                            self.agent.dvr_agent.dvr_mac_address,
+                            constants.PATCH_LV_TO_TUN))]
+                if ip_version == 4:
+                    expected_on_tun_br.insert(1, mock.call(
+                        proto='arp',
+                        nw_dst=gateway_ip, actions='drop',
+                        priority=3, table=constants.DVR_PROCESS,
+                        dl_vlan=lvm.vlan))
+                else:
+                    expected_on_tun_br.insert(1, mock.call(
+                        icmp_type=n_const.ICMPV6_TYPE_RA,
+                        proto='icmp6',
+                        dl_src=self._port.vif_mac,
+                        actions='drop',
+                        priority=3, table=constants.DVR_PROCESS,
+                        dl_vlan=lvm.vlan))
+                self.assertEqual(expected_on_tun_br,
+                                 add_flow_tun_fn.call_args_list)
+                self.agent.port_bound(self._compute_port, self._net_uuid,
+                                      network_type, physical_network,
+                                      segmentation_id,
+                                      self._compute_fixed_ips,
+                                      device_owner, False)
+                expected_on_int_br = [
+                    mock.call(table=constants.DVR_TO_SRC_MAC, priority=4,
+                        dl_dst=self._compute_port.vif_mac,
+                        dl_vlan=lvm.vlan,
+                        actions="strip_vlan,mod_dl_src:%s,"
+                        "output:%s" %
+                        (gateway_mac, self._compute_port.ofport))
+                                ]
+                self.assertEqual(expected_on_int_br,
+                                 add_flow_int_fn.call_args_list)
+                self.assertFalse(add_flow_phys_fn.called)
+                expected_on_int_br = [
+                    mock.call(in_port=self._port.ofport),
+                    mock.call(in_port=self._compute_port.ofport)
+                                      ]
+                self.assertEqual(expected_on_int_br,
+                                 delete_flows_int_fn.call_args_list)
+                self.assertFalse(add_flow_phys_fn.called)
+                self.assertFalse(delete_flows_tun_fn.called)
+                self.assertFalse(delete_flows_phys_fn.called)
+
+    def test_port_bound_for_dvr_with_compute_ports(self):
+        self._test_port_bound_for_dvr_on_vlan_network(
+            device_owner="compute:None")
+        self._test_port_bound_for_dvr_on_vlan_network(
+            device_owner="compute:None", ip_version=6)
+        self._test_port_bound_for_dvr_on_vxlan_network(
+            device_owner="compute:None")
+        self._test_port_bound_for_dvr_on_vxlan_network(
+            device_owner="compute:None", ip_version=6)
+
+    def test_port_bound_for_dvr_with_lbaas_vip_ports(self):
+        self._test_port_bound_for_dvr_on_vlan_network(
+            device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
+        self._test_port_bound_for_dvr_on_vlan_network(
+            device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
+        self._test_port_bound_for_dvr_on_vxlan_network(
+            device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
+        self._test_port_bound_for_dvr_on_vxlan_network(
+            device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
+
+    def test_port_bound_for_dvr_with_dhcp_ports(self):
+        self._test_port_bound_for_dvr_on_vlan_network(
+            device_owner=n_const.DEVICE_OWNER_DHCP)
+        self._test_port_bound_for_dvr_on_vlan_network(
+            device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
+        self._test_port_bound_for_dvr_on_vxlan_network(
+            device_owner=n_const.DEVICE_OWNER_DHCP)
+        self._test_port_bound_for_dvr_on_vxlan_network(
+            device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
+
+    def test_port_bound_for_dvr_with_csnat_ports(self, ofport=10):
+        self._setup_for_dvr_test()
+        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                        'set_db_attribute',
+                        return_value=True):
+            with contextlib.nested(
+                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                           'db_get_val',
+                           return_value=self._old_local_vlan),
+                mock.patch.object(
+                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
+                    return_value={'gateway_ip': '1.1.1.1',
+                                  'cidr': '1.1.1.0/24',
+                                  'ip_version': 4,
+                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                    'get_ports_on_host_by_subnet',
+                    return_value=[]),
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'get_vif_port_by_id',
+                                  return_value=self._port),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
+            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+                  add_flow_tun_fn, delete_flows_tun_fn):
+                self.agent.port_bound(
+                    self._port, self._net_uuid, 'vxlan',
+                    None, None, self._fixed_ips,
+                    n_const.DEVICE_OWNER_ROUTER_SNAT,
+                    False)
+                self.assertTrue(add_flow_int_fn.called)
+                self.assertTrue(delete_flows_int_fn.called)
+
+    def test_treat_devices_removed_for_dvr_interface(self, ofport=10):
+        self._test_treat_devices_removed_for_dvr_interface(ofport)
+        self._test_treat_devices_removed_for_dvr_interface(
+            ofport, ip_version=6)
+
+    def _test_treat_devices_removed_for_dvr_interface(self, ofport=10,
+                                                      ip_version=4):
+        self._setup_for_dvr_test()
+        if ip_version == 4:
+            gateway_ip = '1.1.1.1'
+            cidr = '1.1.1.0/24'
+        else:
+            gateway_ip = '2001:100::1'
+            cidr = '2001:100::0/64'
+        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                        'set_db_attribute',
+                        return_value=True):
+            with contextlib.nested(
+                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                           'db_get_val',
+                           return_value=self._old_local_vlan),
+                mock.patch.object(
+                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
+                    return_value={'gateway_ip': gateway_ip,
+                                  'cidr': cidr,
+                                  'ip_version': ip_version,
+                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                    'get_ports_on_host_by_subnet',
+                    return_value=[]),
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'get_vif_port_by_id',
+                                  return_value=self._port),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
+            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+                  add_flow_tun_fn, delete_flows_tun_fn):
+                self.agent.port_bound(
+                    self._port, self._net_uuid, 'vxlan',
+                    None, None, self._fixed_ips,
+                    n_const.DEVICE_OWNER_DVR_INTERFACE,
+                    False)
+                self.assertTrue(add_flow_tun_fn.called)
+                self.assertTrue(delete_flows_int_fn.called)
+
+        with contextlib.nested(
+            mock.patch.object(self.agent, 'reclaim_local_vlan'),
+            mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
+                              return_value=None),
+            mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+            mock.patch.object(self.agent.dvr_agent.tun_br,
+                              'delete_flows')) as (reclaim_vlan_fn,
+                                                   update_dev_down_fn,
+                                                   delete_flows_int_fn,
+                                                   delete_flows_tun_fn):
+                self.agent.treat_devices_removed([self._port.vif_id])
+                if ip_version == 4:
+                    expected = [mock.call(
+                        proto='arp',
+                        nw_dst=gateway_ip,
+                        table=constants.DVR_PROCESS,
+                        dl_vlan=(
+                            self.agent.local_vlan_map[self._net_uuid].vlan))]
+                else:
+                    expected = [mock.call(
+                        icmp_type=n_const.ICMPV6_TYPE_RA, proto='icmp6',
+                        dl_src='aa:bb:cc:11:22:33',
+                        table=constants.DVR_PROCESS,
+                        dl_vlan=(
+                            self.agent.local_vlan_map[self._net_uuid].vlan))]
+                expected.extend([
+                    mock.call(
+                        table=constants.DVR_PROCESS,
+                        dl_dst=self._port.vif_mac,
+                        dl_vlan=(
+                            self.agent.local_vlan_map[self._net_uuid].vlan)),
+                    mock.call(
+                        table=constants.DVR_PROCESS,
+                        dl_vlan=(
+                            self.agent.local_vlan_map[self._net_uuid].vlan),
+                        dl_src=self._port.vif_mac)
+                ])
+                self.assertEqual(expected, delete_flows_tun_fn.call_args_list)
+
+    def _test_treat_devices_removed_for_dvr(self, device_owner, ip_version=4):
+        self._setup_for_dvr_test()
+        if ip_version == 4:
+            gateway_ip = '1.1.1.1'
+            cidr = '1.1.1.0/24'
+        else:
+            gateway_ip = '2001:100::1'
+            cidr = '2001:100::0/64'
+        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                        'set_db_attribute',
+                        return_value=True):
+            with contextlib.nested(
+                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                           'db_get_val',
+                           return_value=self._old_local_vlan),
+                mock.patch.object(
+                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
+                    return_value={'gateway_ip': gateway_ip,
+                                  'cidr': cidr,
+                                  'ip_version': ip_version,
+                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                    'get_ports_on_host_by_subnet',
+                    return_value=[]),
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'get_vif_port_by_id',
+                                  return_value=self._port),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
+            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+                  add_flow_tun_fn, delete_flows_tun_fn):
+                self.agent.port_bound(
+                    self._port, self._net_uuid, 'vxlan',
+                    None, None, self._fixed_ips,
+                    n_const.DEVICE_OWNER_DVR_INTERFACE,
+                    False)
+                self.agent.port_bound(self._compute_port,
+                                      self._net_uuid, 'vxlan',
+                                      None, None,
+                                      self._compute_fixed_ips,
+                                      device_owner, False)
+                self.assertTrue(add_flow_tun_fn.called)
+                self.assertTrue(add_flow_int_fn.called)
+                self.assertTrue(delete_flows_int_fn.called)
+
+        with contextlib.nested(
+            mock.patch.object(self.agent, 'reclaim_local_vlan'),
+            mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
+                              return_value=None),
+            mock.patch.object(self.agent.dvr_agent.int_br,
+                              'delete_flows')) as (reclaim_vlan_fn,
+                                                   update_dev_down_fn,
+                                                   delete_flows_int_fn):
+                self.agent.treat_devices_removed([self._compute_port.vif_id])
+                expected = [
+                    mock.call(
+                        table=constants.DVR_TO_SRC_MAC,
+                        dl_dst=self._compute_port.vif_mac,
+                        dl_vlan=(
+                            self.agent.local_vlan_map[self._net_uuid].vlan))]
+                self.assertEqual(expected, delete_flows_int_fn.call_args_list)
+
+    def test_treat_devices_removed_for_dvr_with_compute_ports(self):
+        self._test_treat_devices_removed_for_dvr(
+            device_owner="compute:None")
+        self._test_treat_devices_removed_for_dvr(
+            device_owner="compute:None", ip_version=6)
+
+    def test_treat_devices_removed_for_dvr_with_lbaas_vip_ports(self):
+        self._test_treat_devices_removed_for_dvr(
+            device_owner=n_const.DEVICE_OWNER_LOADBALANCER)
+        self._test_treat_devices_removed_for_dvr(
+            device_owner=n_const.DEVICE_OWNER_LOADBALANCER, ip_version=6)
+
+    def test_treat_devices_removed_for_dvr_with_dhcp_ports(self):
+        self._test_treat_devices_removed_for_dvr(
+            device_owner=n_const.DEVICE_OWNER_DHCP)
+        self._test_treat_devices_removed_for_dvr(
+            device_owner=n_const.DEVICE_OWNER_DHCP, ip_version=6)
+
+    def test_treat_devices_removed_for_dvr_csnat_port(self, ofport=10):
+        self._setup_for_dvr_test()
+        with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                        'set_db_attribute',
+                        return_value=True):
+            with contextlib.nested(
+                mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
+                           'db_get_val',
+                           return_value=self._old_local_vlan),
+                mock.patch.object(
+                    self.agent.dvr_agent.plugin_rpc, 'get_subnet_for_dvr',
+                    return_value={'gateway_ip': '1.1.1.1',
+                                  'cidr': '1.1.1.0/24',
+                                  'ip_version': 4,
+                                  'gateway_mac': 'aa:bb:cc:11:22:33'}),
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                    'get_ports_on_host_by_subnet',
+                    return_value=[]),
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'get_vif_port_by_id',
+                                  return_value=self._port),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows')
+            ) as (get_ovs_db_func, get_subnet_fn, get_cphost_fn,
+                  get_vif_fn, add_flow_int_fn, delete_flows_int_fn,
+                  add_flow_tun_fn, delete_flows_tun_fn):
+                self.agent.port_bound(
+                    self._port, self._net_uuid, 'vxlan',
+                    None, None, self._fixed_ips,
+                    n_const.DEVICE_OWNER_ROUTER_SNAT,
+                    False)
+                self.assertTrue(add_flow_int_fn.called)
+                self.assertTrue(delete_flows_int_fn.called)
+
+        with contextlib.nested(
+            mock.patch.object(self.agent, 'reclaim_local_vlan'),
+            mock.patch.object(self.agent.plugin_rpc, 'update_device_down',
+                              return_value=None),
+            mock.patch.object(self.agent.dvr_agent.int_br,
+                              'delete_flows')) as (reclaim_vlan_fn,
+                                                   update_dev_down_fn,
+                                                   delete_flows_int_fn):
+                self.agent.treat_devices_removed([self._port.vif_id])
+                self.assertTrue(delete_flows_int_fn.called)
+
+    def test_setup_dvr_flows_on_int_br(self):
+        self._setup_for_dvr_test()
+        with contextlib.nested(
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'remove_all_flows'),
+                mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+                mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+                mock.patch.object(
+                    self.agent.dvr_agent.plugin_rpc,
+                    'get_dvr_mac_address_list',
+                    return_value=[{'host': 'cn1',
+                                   'mac_address': 'aa:bb:cc:dd:ee:ff'},
+                                  {'host': 'cn2',
+                                   'mac_address': '11:22:33:44:55:66'}])) as \
+            (remove_flows_fn, add_int_flow_fn, add_tun_flow_fn,
+             get_mac_list_fn):
+            self.agent.dvr_agent.setup_dvr_flows_on_integ_br()
+            self.assertTrue(self.agent.dvr_agent.in_distributed_mode())
+            physical_networks = self.agent.dvr_agent.bridge_mappings.keys()
+            ioport = self.agent.dvr_agent.int_ofports[physical_networks[0]]
+            expected = [
+                    mock.call(table=constants.CANARY_TABLE,
+                              priority=0,
+                              actions="drop"),
+                    mock.call(table=constants.DVR_TO_SRC_MAC,
+                             priority=1,
+                             actions="drop"),
+                    mock.call(table=constants.DVR_TO_SRC_MAC_VLAN,
+                             priority=1,
+                             actions="drop"),
+                    mock.call(table=constants.LOCAL_SWITCHING,
+                             priority=1,
+                             actions="normal"),
+                    mock.call(
+                        table=constants.LOCAL_SWITCHING, priority=2,
+                        actions="drop",
+                        in_port=ioport)]
+            self.assertTrue(remove_flows_fn.called)
+            self.assertEqual(expected, add_int_flow_fn.call_args_list)
+            self.assertEqual(add_int_flow_fn.call_count, 5)
+
+    def test_get_dvr_mac_address(self):
+        self._setup_for_dvr_test()
+        self.agent.dvr_agent.dvr_mac_address = None
+        with mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                               'get_dvr_mac_address_by_host',
+                               return_value={'host': 'cn1',
+                                  'mac_address': 'aa:22:33:44:55:66'}):
+            self.agent.dvr_agent.get_dvr_mac_address()
+            self.assertEqual('aa:22:33:44:55:66',
+                             self.agent.dvr_agent.dvr_mac_address)
+            self.assertTrue(self.agent.dvr_agent.in_distributed_mode())
+
+    def test_get_dvr_mac_address_exception(self):
+        self._setup_for_dvr_test()
+        self.agent.dvr_agent.dvr_mac_address = None
+        with contextlib.nested(
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                               'get_dvr_mac_address_by_host',
+                               side_effect=oslo_messaging.RemoteError),
+                mock.patch.object(self.agent.dvr_agent.int_br,
+                                  'add_flow')) as (gd_mac, add_int_flow_fn):
+
+            self.agent.dvr_agent.get_dvr_mac_address()
+            self.assertIsNone(self.agent.dvr_agent.dvr_mac_address)
+            self.assertFalse(self.agent.dvr_agent.in_distributed_mode())
+            self.assertEqual(add_int_flow_fn.call_count, 1)
+
+    def test_get_dvr_mac_address_retried(self):
+        valid_entry = {'host': 'cn1', 'mac_address': 'aa:22:33:44:55:66'}
+        raise_timeout = oslo_messaging.MessagingTimeout()
+        # Raise a timeout the first 2 times it calls get_dvr_mac_address()
+        self._setup_for_dvr_test()
+        self.agent.dvr_agent.dvr_mac_address = None
+        with mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                               'get_dvr_mac_address_by_host',
+                               side_effect=(raise_timeout, raise_timeout,
+                                            valid_entry)):
+            self.agent.dvr_agent.get_dvr_mac_address()
+            self.assertEqual('aa:22:33:44:55:66',
+                             self.agent.dvr_agent.dvr_mac_address)
+            self.assertTrue(self.agent.dvr_agent.in_distributed_mode())
+            self.assertEqual(self.agent.dvr_agent.plugin_rpc.
+                             get_dvr_mac_address_by_host.call_count, 3)
+
+    def test_get_dvr_mac_address_retried_max(self):
+        raise_timeout = oslo_messaging.MessagingTimeout()
+        # Raise a timeout every time until we give up, currently 5 tries
+        self._setup_for_dvr_test()
+        self.agent.dvr_agent.dvr_mac_address = None
+        with contextlib.nested(
+                mock.patch.object(self.agent.dvr_agent.plugin_rpc,
+                                 'get_dvr_mac_address_by_host',
+                                 side_effect=raise_timeout),
+                mock.patch.object(utils, "execute"),
+        ) as (rpc_mock, execute_mock):
+            self.agent.dvr_agent.get_dvr_mac_address()
+            self.assertIsNone(self.agent.dvr_agent.dvr_mac_address)
+            self.assertFalse(self.agent.dvr_agent.in_distributed_mode())
+            self.assertEqual(self.agent.dvr_agent.plugin_rpc.
+                             get_dvr_mac_address_by_host.call_count, 5)
+
+    def test_dvr_mac_address_update(self):
+        self._setup_for_dvr_test()
+        newhost = 'cn2'
+        newmac = 'aa:bb:cc:dd:ee:ff'
+        int_ofport = self.agent.dvr_agent.int_ofports['physeth1']
+        patch_int_ofport = self.agent.dvr_agent.patch_int_ofport
+        patch_tun_ofport = self.agent.dvr_agent.patch_tun_ofport
+        with contextlib.nested(
+            mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+            mock.patch.object(self.agent.dvr_agent.tun_br, 'add_flow'),
+            mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+            mock.patch.object(self.agent.dvr_agent.phys_brs['physeth1'],
+                              'add_flow')
+        ) as (add_flow_fn, add_flow_tn_fn, del_flows_fn, add_flow_phys_fn):
+            self.agent.dvr_agent.\
+                dvr_mac_address_update(
+                    dvr_macs=[{'host': newhost,
+                               'mac_address': newmac}])
+            expected = [
+                    mock.call(table=constants.LOCAL_SWITCHING,
+                              priority=4,
+                              in_port=int_ofport,
+                              dl_src=newmac,
+                              actions="resubmit(,%s)" %
+                              constants.DVR_TO_SRC_MAC_VLAN),
+                    mock.call(table=constants.LOCAL_SWITCHING,
+                              priority=2,
+                              in_port=patch_tun_ofport,
+                              dl_src=newmac,
+                              actions="resubmit(,%s)" %
+                              constants.DVR_TO_SRC_MAC)]
+            self.assertEqual(expected, add_flow_fn.call_args_list)
+            add_flow_phys_fn.assert_called_with(
+                    table=constants.DVR_NOT_LEARN_VLAN,
+                    priority=2,
+                    dl_src=newmac,
+                    actions="output:%s" %
+                    self.agent.dvr_agent.phys_ofports['physeth1'])
+            add_flow_tn_fn.assert_called_with(table=constants.DVR_NOT_LEARN,
+                                              priority=1,
+                                              dl_src=newmac,
+                                              actions="output:%s"
+                                              % patch_int_ofport)
+            self.assertFalse(del_flows_fn.called)
+        with contextlib.nested(
+            mock.patch.object(self.agent.dvr_agent.int_br, 'add_flow'),
+            mock.patch.object(self.agent.dvr_agent.tun_br, 'delete_flows'),
+            mock.patch.object(self.agent.dvr_agent.int_br, 'delete_flows'),
+            mock.patch.object(self.agent.dvr_agent.phys_brs['physeth1'],
+                              'delete_flows'),
+        ) as (add_flow_fn, del_flows_tn_fn, del_flows_fn, del_flows_phys_fn):
+            self.agent.dvr_agent.dvr_mac_address_update(dvr_macs=[])
+            ioport = self.agent.dvr_agent.int_ofports['physeth1']
+            expected = [
+                 mock.call(table=constants.LOCAL_SWITCHING,
+                           in_port=ioport,
+                           dl_src=newmac),
+                 mock.call(table=constants.LOCAL_SWITCHING,
+                           in_port=patch_tun_ofport,
+                           dl_src=newmac)]
+            self.assertEqual(expected, del_flows_fn.call_args_list)
+            del_flows_phys_fn.asert_called_with(
+                    table=constants.DVR_NOT_LEARN_VLAN,
+                    dl_src=newmac)
+            del_flows_tn_fn.assert_called_with(table=constants.DVR_NOT_LEARN,
+                                               dl_src=newmac)
+            self.assertFalse(add_flow_fn.called)
+
+    def test_ovs_restart(self):
+        self._setup_for_dvr_test()
+        reset_methods = (
+            'reset_ovs_parameters', 'reset_dvr_parameters',
+            'setup_dvr_flows_on_integ_br', 'setup_dvr_flows_on_tun_br',
+            'setup_dvr_flows_on_phys_br', 'setup_dvr_mac_flows_on_all_brs')
+        reset_mocks = [mock.patch.object(self.agent.dvr_agent, method).start()
+                       for method in reset_methods]
+        with contextlib.nested(
+            mock.patch.object(self.agent, 'check_ovs_status',
+                              return_value=constants.OVS_RESTARTED),
+            mock.patch.object(self.agent, '_agent_has_updates',
+                              side_effect=TypeError('loop exit'))
+        ):
+            # block RPC calls and bridge calls
+            self.agent.setup_physical_bridges = mock.Mock()
+            self.agent.setup_integration_br = mock.Mock()
+            self.agent.reset_tunnel_br = mock.Mock()
+            self.agent.state_rpc = mock.Mock()
+            try:
+                self.agent.rpc_loop(polling_manager=mock.Mock())
+            except TypeError:
+                pass
+        self.assertTrue(all([x.called for x in reset_mocks]))