From cbaa3fe07b68e650d7c7714775e56f4e28c3af82 Mon Sep 17 00:00:00 2001 From: Irena Berezovsky Date: Tue, 22 Jul 2014 18:13:00 +0300 Subject: [PATCH] Fix ML2 Plugin binding:profile update The current fix changes the logic for binding:profile update. The binding:profile should be considered as changed once it is present in the port attributes and differs from existing binding:profile. The specified binding:profile with None value should be treated as request to clear binding:profile. Change-Id: Ibda9a1beec697fbee5be0ee379349035c3626509 Closes-Bug: 1338202 --- neutron/plugins/ml2/plugin.py | 11 +++++++---- neutron/tests/unit/ml2/test_ml2_plugin.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index bae54b9fc47..5f97f35c6ac 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -229,10 +229,13 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, binding.vnic_type = vnic_type changes = True - # CLI can't send {}, so treat None as {}. - profile = attrs and attrs.get(portbindings.PROFILE) or {} - if (profile is not attributes.ATTR_NOT_SPECIFIED and - self._get_profile(binding) != profile): + # treat None as clear of profile. + profile = None + if attrs and portbindings.PROFILE in attrs: + profile = attrs.get(portbindings.PROFILE) or {} + + if profile not in (None, attributes.ATTR_NOT_SPECIFIED, + self._get_profile(binding)): binding.profile = jsonutils.dumps(profile) if len(binding.profile) > models.BINDING_PROFILE_LEN: msg = _("binding:profile value too large") diff --git a/neutron/tests/unit/ml2/test_ml2_plugin.py b/neutron/tests/unit/ml2/test_ml2_plugin.py index 0ab7349e8c2..45cab5426d5 100644 --- a/neutron/tests/unit/ml2/test_ml2_plugin.py +++ b/neutron/tests/unit/ml2/test_ml2_plugin.py @@ -250,6 +250,20 @@ class TestMl2PortBinding(Ml2PluginV2TestCase, # should have returned before calling _make_port_dict self.assertFalse(mpd_mock.mock_calls) + def test_port_binding_profile_not_changed(self): + profile = {'e': 5} + profile_arg = {portbindings.PROFILE: profile} + with self.port(arg_list=(portbindings.PROFILE,), + **profile_arg) as port: + self._check_port_binding_profile(port['port'], profile) + port_id = port['port']['id'] + state_arg = {'admin_state_up': True} + port = self._update('ports', port_id, + {'port': state_arg})['port'] + self._check_port_binding_profile(port, profile) + port = self._show('ports', port_id)['port'] + self._check_port_binding_profile(port, profile) + class TestMl2PortBindingNoSG(TestMl2PortBinding): HAS_PORT_FILTER = False