]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add the rebinding chance in _bind_port_if_needed
authorYalei Wang <yalei.wang@intel.com>
Thu, 8 Jan 2015 02:46:08 +0000 (10:46 +0800)
committerYalei Wang <yalei.wang@intel.com>
Fri, 6 Feb 2015 21:42:28 +0000 (05:42 +0800)
Make function _bind_port_if_needed to bind at least one time when the port's
binding status passed in is already in binding_failed.

Change-Id: I823ff5ca66833cdca459f13ab28f5075ae03ded3
Closes-Bug: #1399249

neutron/plugins/ml2/plugin.py
neutron/tests/unit/ml2/test_ml2_plugin.py

index a303fac35693409ff49a594d919d9aac6e34bea6..66a43e1b747814ff3a44739a743dd19205f557c5 100644 (file)
@@ -260,7 +260,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
             # First, determine whether it is necessary and possible to
             # bind the port.
             binding = context._binding
-            if (binding.vif_type != portbindings.VIF_TYPE_UNBOUND
+            if (binding.vif_type not in [portbindings.VIF_TYPE_UNBOUND,
+                                         portbindings.VIF_TYPE_BINDING_FAILED]
                 or not binding.host):
                 # We either don't need to bind the port, or can't, so
                 # notify if needed and return.
@@ -298,12 +299,15 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
                 LOG.debug("Port %s has been deleted concurrently",
                           port_id)
                 return context
+
+            context = new_context
+
+            if (context._binding.vif_type ==
+                    portbindings.VIF_TYPE_BINDING_FAILED):
+                return context
             # Need to notify if we succeed and our results were
             # committed.
-            if did_commit and (new_context._binding.vif_type !=
-                               portbindings.VIF_TYPE_BINDING_FAILED):
-                need_notify = True
-            context = new_context
+            need_notify |= did_commit
 
     def _bind_port(self, orig_context):
         # Construct a new PortContext from the one from the previous
index f05893d221f2b687fbe4217cf65b187b85e2900e..9cc0469888ed290a539c0a4fbd7b1803ebc12599 100644 (file)
@@ -457,6 +457,54 @@ class TestMl2PortBinding(Ml2PluginV2TestCase,
             # should have returned before calling _make_port_dict
             self.assertFalse(mpd_mock.mock_calls)
 
+    def test_bind_port_if_needed(self):
+        # create a port and set its vif_type to binding_failed
+        with self.port() as port:
+            plugin = manager.NeutronManager.get_plugin()
+            binding = ml2_db.get_locked_port_and_binding(self.context.session,
+                                                         port['port']['id'])[1]
+            binding['host'] = 'test'
+
+            binding['vif_type'] = portbindings.VIF_TYPE_BINDING_FAILED
+            mech_context = driver_context.PortContext(
+                plugin, self.context, port['port'],
+                plugin.get_network(self.context, port['port']['network_id']),
+                binding)
+
+        # test when _commit_port_binding return binding_failed
+        self._test_bind_port_if_needed(plugin, mech_context, False)
+        # test when _commit_port_binding NOT return binding_failed
+        self._test_bind_port_if_needed(plugin, mech_context, True)
+
+    def _test_bind_port_if_needed(self, plugin, mech_context, commit_fail):
+        # mock _commit_port_binding
+        commit_context = mock.MagicMock()
+        if commit_fail:
+            commit_context._binding.vif_type = (
+                    portbindings.VIF_TYPE_BINDING_FAILED)
+        else:
+            commit_context._binding.vif_type = portbindings.VIF_TYPE_OVS
+
+        with contextlib.nested(
+            mock.patch('neutron.plugins.ml2.plugin.'
+                       'db.get_locked_port_and_binding',
+                       return_value=(None, None)),
+            mock.patch('neutron.plugins.ml2.plugin.Ml2Plugin._bind_port'),
+            mock.patch('neutron.plugins.ml2.plugin.'
+                       'Ml2Plugin._commit_port_binding',
+                       return_value=(commit_context, False))
+        ) as (glpab_mock, bd_mock, commit_mock):
+            bound_context = plugin._bind_port_if_needed(mech_context)
+            # check _bind_port be called
+            self.assertTrue(bd_mock.called)
+
+            if commit_fail:
+                self.assertEqual(portbindings.VIF_TYPE_BINDING_FAILED,
+                        bound_context._binding.vif_type)
+            else:
+                self.assertEqual(portbindings.VIF_TYPE_OVS,
+                        bound_context._binding.vif_type)
+
     def test_port_binding_profile_not_changed(self):
         profile = {'e': 5}
         profile_arg = {portbindings.PROFILE: profile}