]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix PortNotFound error during update_device_up for DVR
authorarmando-migliaccio <armamig@gmail.com>
Wed, 13 Aug 2014 18:39:07 +0000 (11:39 -0700)
committerarmando-migliaccio <armamig@gmail.com>
Wed, 13 Aug 2014 18:53:59 +0000 (11:53 -0700)
An agent's request to update the ARP entry for a VM port
may come after a deletion request has been processed,
resulting in a PortNotFound exception being raised.

This patch takes care of this condition. A test has
been added, which required a minor refactoring of the
test case class, in order to accommodate the use of
side effects for the objects being mocked.

Closes-bug: #1356120

Change-Id: I40d635bcf47c683663cb4dedf20323902dff2c7f

neutron/plugins/ml2/rpc.py
neutron/tests/unit/ml2/test_rpcapi.py

index ae447fa8e431d08d7cd03654652d8d5d34313961..9dcf2c4eaa7615b22e2b1497dee9e00ba443c37e 100644 (file)
@@ -16,6 +16,7 @@
 from neutron.agent import securitygroups_rpc as sg_rpc
 from neutron.api.rpc.handlers import dvr_rpc
 from neutron.common import constants as q_const
+from neutron.common import exceptions
 from neutron.common import rpc as n_rpc
 from neutron.common import topics
 from neutron.common import utils
@@ -194,7 +195,10 @@ class RpcCallbacks(n_rpc.RpcCallback,
         if (l3plugin and
             utils.is_extension_supported(l3plugin,
                                          q_const.L3_DISTRIBUTED_EXT_ALIAS)):
-            l3plugin.dvr_vmarp_table_update(rpc_context, port_id, "add")
+            try:
+                l3plugin.dvr_vmarp_table_update(rpc_context, port_id, "add")
+            except exceptions.PortNotFound:
+                LOG.debug('Port %s not found during ARP update', port_id)
 
     def get_dvr_mac_address_by_host(self, rpc_context, **kwargs):
         host = kwargs.get('host')
index 357312c1694b8420af14de1539c687a2b551b6a7..71d80d040d994d9829253182efb317480f931de0 100644 (file)
@@ -20,6 +20,7 @@ Unit Tests for ml2 rpc
 import mock
 
 from neutron.agent import rpc as agent_rpc
+from neutron.common import exceptions
 from neutron.common import rpc as n_rpc
 from neutron.common import topics
 from neutron.openstack.common import context
@@ -28,41 +29,51 @@ from neutron.plugins.ml2 import rpc as plugin_rpc
 from neutron.tests import base
 
 
-class RpcCallbacks(base.BaseTestCase):
+class RpcCallbacksTestCase(base.BaseTestCase):
 
     def setUp(self):
-        super(RpcCallbacks, self).setUp()
+        super(RpcCallbacksTestCase, self).setUp()
         self.callbacks = plugin_rpc.RpcCallbacks(mock.Mock(), mock.Mock())
+        self.manager = mock.patch.object(
+            plugin_rpc.manager, 'NeutronManager').start()
+        self.l3plugin = mock.Mock()
+        self.manager.get_service_plugins.return_value = {
+            'L3_ROUTER_NAT': self.l3plugin
+        }
 
     def _test_update_device_up(self, extensions, kwargs):
-        with mock.patch.object(plugin_rpc.manager, 'NeutronManager') as mgr:
-            with mock.patch.object(self.callbacks, '_device_to_port_id'):
-                mock_l3plugin = mock.Mock()
-                mgr.get_service_plugins.return_value = {
-                    'L3_ROUTER_NAT': mock_l3plugin
-                }
-                type(mock_l3plugin).supported_extension_aliases = (
-                    mock.PropertyMock(return_value=extensions))
-                self.callbacks.update_device_up(mock.ANY, **kwargs)
-        return mock_l3plugin
+        with mock.patch.object(self.callbacks, '_device_to_port_id'):
+            type(self.l3plugin).supported_extension_aliases = (
+                mock.PropertyMock(return_value=extensions))
+            self.callbacks.update_device_up(mock.ANY, **kwargs)
 
     def test_update_device_up_without_dvr(self):
         kwargs = {
             'agent_id': 'foo_agent',
             'device': 'foo_device'
         }
-        l3plugin = self._test_update_device_up(['router'], kwargs)
-        self.assertFalse(l3plugin.dvr_vmarp_table_update.call_count)
+        self._test_update_device_up(['router'], kwargs)
+        self.assertFalse(self.l3plugin.dvr_vmarp_table_update.call_count)
 
     def test_update_device_up_with_dvr(self):
         kwargs = {
             'agent_id': 'foo_agent',
             'device': 'foo_device'
         }
-        l3plugin = self._test_update_device_up(['router', 'dvr'], kwargs)
-        l3plugin.dvr_vmarp_table_update.assert_called_once_with(
+        self._test_update_device_up(['router', 'dvr'], kwargs)
+        self.l3plugin.dvr_vmarp_table_update.assert_called_once_with(
             mock.ANY, mock.ANY, 'add')
 
+    def test_update_device_up_with_dvr_when_port_not_found(self):
+        kwargs = {
+            'agent_id': 'foo_agent',
+            'device': 'foo_device'
+        }
+        self.l3plugin.dvr_vmarp_table_update.side_effect = (
+            exceptions.PortNotFound(port_id='foo_port_id'))
+        self._test_update_device_up(['router', 'dvr'], kwargs)
+        self.assertTrue(self.l3plugin.dvr_vmarp_table_update.call_count)
+
 
 class RpcApiTestCase(base.BaseTestCase):