]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix PortNotFound exception during sync_routers
authorarmando-migliaccio <armamig@gmail.com>
Tue, 12 Aug 2014 05:43:31 +0000 (22:43 -0700)
committerarmando-migliaccio <armamig@gmail.com>
Wed, 13 Aug 2014 14:04:32 +0000 (07:04 -0700)
This trace is observed when an L3 agent invokes
sync_routers right about the same time a port
interface is removed from a router.

Related-bug: #1355409

Change-Id: I825b25080cbf054462318fc01248692b9e0e4ecb

neutron/db/l3_rpc_base.py
neutron/tests/unit/test_l3_plugin.py

index e238e7be90db03f970cec24d69838f60c7454481..2886f886d0b18f49ef4fe88c5e45b70766d16c86 100644 (file)
@@ -16,6 +16,7 @@
 from oslo.config import cfg
 
 from neutron.common import constants
+from neutron.common import exceptions
 from neutron.common import utils
 from neutron import context as neutron_context
 from neutron.extensions import l3
@@ -106,8 +107,13 @@ class L3RpcCallbackMixin(object):
              portbindings.VIF_TYPE_BINDING_FAILED)):
             # All ports, including ports created for SNAT'ing for
             # DVR are handled here
-            self.plugin.update_port(context, port['id'],
-                                    {'port': {portbindings.HOST_ID: host}})
+            try:
+                self.plugin.update_port(context, port['id'],
+                                        {'port': {portbindings.HOST_ID: host}})
+            except exceptions.PortNotFound:
+                LOG.debug("Port %(port)s not found while updating "
+                          "agent binding for router %(router)s."
+                          % {"port": port['id'], "router": router_id})
         elif (port and
               port.get('device_owner') ==
               constants.DEVICE_OWNER_DVR_INTERFACE):
index 7dc665674509c12627cb51425737b5b5a29940d8..50f7ba7dc81d8b4d4df8f8591a8fa786fcbfb6fe 100644 (file)
@@ -38,6 +38,7 @@ from neutron.db import l3_rpc_base
 from neutron.db import model_base
 from neutron.extensions import external_net
 from neutron.extensions import l3
+from neutron.extensions import portbindings
 from neutron import manager
 from neutron.openstack.common import importutils
 from neutron.openstack.common import log as logging
@@ -2048,6 +2049,41 @@ class L3NatDBIntAgentSchedulingTestCase(L3BaseForIntTests,
                         expected_code=exc.HTTPBadRequest.code)
 
 
+class L3RpcCallbackMixinTestCase(base.BaseTestCase):
+
+    def setUp(self):
+        super(L3RpcCallbackMixinTestCase, self).setUp()
+        self.mock_plugin = mock.patch.object(
+            l3_rpc_base.L3RpcCallbackMixin,
+            'plugin', new_callable=mock.PropertyMock).start()
+        self.mock_l3plugin = mock.patch.object(
+            l3_rpc_base.L3RpcCallbackMixin,
+            'l3plugin', new_callable=mock.PropertyMock).start()
+        self.mixin = l3_rpc_base.L3RpcCallbackMixin()
+
+    def test__ensure_host_set_on_port_update_on_concurrent_delete(self):
+        port_id = 'foo_port_id'
+        port = {
+            'id': port_id,
+            'device_owner': 'compute:None',
+            portbindings.HOST_ID: '',
+            portbindings.VIF_TYPE: portbindings.VIF_TYPE_BINDING_FAILED
+        }
+        router_id = 'foo_router_id'
+        self.mixin.plugin.update_port.side_effect = n_exc.PortNotFound(
+            port_id=port_id)
+        with mock.patch.object(l3_rpc_base.LOG, 'debug') as mock_log:
+            self.mixin._ensure_host_set_on_port(
+                mock.ANY, mock.ANY, port, router_id)
+        self.mixin.plugin.update_port.assert_called_once_with(
+            mock.ANY, port_id, {'port': {'binding:host_id': mock.ANY}})
+        self.assertTrue(mock_log.call_count)
+        expected_message = ('Port foo_port_id not found while updating '
+                            'agent binding for router foo_router_id.')
+        actual_message = mock_log.call_args[0][0]
+        self.assertEqual(expected_message, actual_message)
+
+
 class L3AgentDbIntTestCase(L3BaseForIntTests, L3AgentDbTestCaseBase):
 
     """Unit tests for methods called by the L3 agent for