Fix PortNotFound exception during sync_routers

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
This commit is contained in:
armando-migliaccio 2014-08-11 22:43:31 -07:00
parent fe49457605
commit 2affc39d3a
2 changed files with 44 additions and 2 deletions

View 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):

View 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