Do not trigger agent notification if bindings do not change

The method _process_port_bindings for the ml2 plugin should not
return True when the host binding does not change, otherwise an
unnecessary notification will be sent to the agent

Closes-Bug: #1255680
Related-Bug: #1253896
Partially Implements: neutron-tempest-parallel

Change-Id: I8a40090af347ca430ff6c8e2211fa34bb2bd0f8c
This commit is contained in:
Salvatore Orlando 2013-11-27 13:26:07 -08:00
parent 1020281a0a
commit 2d216389bb
2 changed files with 49 additions and 2 deletions

View File

@ -203,7 +203,6 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
binding = mech_context._binding
port = mech_context.current
self._update_port_dict_binding(port, binding)
host = attrs and attrs.get(portbindings.HOST_ID)
host_set = attributes.is_attr_set(host)
@ -214,6 +213,11 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
self.mechanism_manager.unbind_port(mech_context)
self._update_port_dict_binding(port, binding)
# Return True only if an agent notification is needed.
# This will happen if a new host was specified and that host
# differs from the current one. Note that host_set is True
# even if the host is an empty string
ret_value = host_set and binding.get('host') != host
if host_set:
binding.host = host
port[portbindings.HOST_ID] = host
@ -222,7 +226,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
self.mechanism_manager.bind_port(mech_context)
self._update_port_dict_binding(port, binding)
return True
return ret_value
def _update_port_dict_binding(self, port, binding):
port[portbindings.HOST_ID] = binding.host

View File

@ -13,6 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
from neutron import context
from neutron.extensions import portbindings
from neutron import manager
from neutron.plugins.ml2 import config as config
@ -76,3 +79,43 @@ class PortBindingTestCase(test_plugin.NeutronDbPluginV2TestCase):
self._test_port_binding("host-bridge-filter",
portbindings.VIF_TYPE_BRIDGE,
True, True)
def _test_update_port_binding(self, host, new_host=None):
with mock.patch.object(self.plugin,
'_notify_port_updated') as notify_mock:
host_arg = {portbindings.HOST_ID: host}
update_body = {'name': 'test_update'}
if new_host is not None:
update_body[portbindings.HOST_ID] = new_host
with self.port(name='name', arg_list=(portbindings.HOST_ID,),
**host_arg) as port:
neutron_context = context.get_admin_context()
updated_port = self._update('ports', port['port']['id'],
{'port': update_body},
neutron_context=neutron_context)
port_data = updated_port['port']
if new_host is not None:
self.assertEqual(port_data['binding:host_id'], new_host)
else:
self.assertEqual(port_data['binding:host_id'], host)
if new_host is not None and new_host != host:
notify_mock.assert_called_once_with(mock.ANY)
else:
self.assertFalse(notify_mock.called)
def test_update_with_new_host_binding_notifies_agent(self):
self._test_update_port_binding('host-ovs-no-filter',
'host-bridge-no-filter')
def test_update_with_same_host_binding_does_not_notify(self):
self._test_update_port_binding('host-ovs-no-filter',
'host-ovs-no-filter')
def test_update_without_binding_does_not_notify(self):
self._test_update_port_binding('host-ovs-no-filter')
def testt_update_from_empty_to_host_binding_notifies_agent(self):
self._test_update_port_binding('', 'host-ovs-no-filter')
def test_update_from_host_to_empty_binding_notifies_agent(self):
self._test_update_port_binding('host-ovs-no-filter', '')