summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSlawek Kaplonski <skaplons@redhat.com>2022-08-01 13:00:28 +0200
committerSlawek Kaplonski <skaplons@redhat.com>2022-08-29 08:53:18 +0000
commit39f7e1299364f3eca6375c178b604f70a05c0d81 (patch)
treed3708e0c028a096a94838dabb75efe0f36f21797
parent80ad263e28877d37862aee79c340fba5e6330da3 (diff)
downloadneutron-39f7e1299364f3eca6375c178b604f70a05c0d81.tar.gz
Bump revision number of objects when description is changed
"Description" attribute belongs to the StandardAttribute class from which many other classes inherits (like e.g. Network, Port or Subnet). In case when only description of object is updated, revision number of the object should be bumped but it wasn't the case for all of the objects. For example updated description of the Network or Router didn't bumped its revision_number. It was like that because StandardAttribute object was the only one which was dirty in the session, and as it is not member of the HasStandardAttibutes class, it was filtered out. Now, to fix that problem revision_plugin looks in the session.dirty list for objects which inherits from HasStandardAttibutes class (as it was before) but also for StandardAttribute objects to bump revision numbers. Closes-Bug: #1981817 Closes-Bug: #1865173 Change-Id: I79b40a8ae5d594ed6fc875572663469c8b701202 (cherry picked from commit 4c9cb83d6b46a6425e603194649a61f51a07a307)
-rw-r--r--neutron/services/revisions/revision_plugin.py33
-rw-r--r--neutron/tests/unit/services/revisions/test_revision_plugin.py16
2 files changed, 44 insertions, 5 deletions
diff --git a/neutron/services/revisions/revision_plugin.py b/neutron/services/revisions/revision_plugin.py
index bf94fb5d6a..b6484945c6 100644
--- a/neutron/services/revisions/revision_plugin.py
+++ b/neutron/services/revisions/revision_plugin.py
@@ -49,15 +49,38 @@ class RevisionPlugin(service_base.ServicePluginBase):
db_api.sqla_listen(se.Session, 'after_rollback',
self._clear_rev_bumped_flags)
+ def _get_objects_to_bump_revision(self, dirty_objects):
+ all_std_attr_objects = []
+ objects_to_bump_revision = []
+ for dirty_object in dirty_objects:
+ if isinstance(dirty_object, standard_attr.HasStandardAttributes):
+ objects_to_bump_revision.append(dirty_object)
+ elif isinstance(dirty_object, standard_attr.StandardAttribute):
+ all_std_attr_objects.append(dirty_object)
+
+ # Now as we have all objects divided into 2 groups, we need to ensure
+ # that we don't have revision number for the same one in both groups.
+ # It may happen e.g. for the Subnet object, as during update of Subnet,
+ # both Subnet and StandardAttribute objects of that subnet are dirty.
+ # But for example for Network, when only description is changed, only
+ # StandardAttribute object is in the dirty objects set.
+ std_attr_ids = [o.standard_attr_id for o in objects_to_bump_revision]
+
+ # NOTE(slaweq): StandardAttribute objects which have "description"
+ # field modified, should have revision bumped too
+ objects_to_bump_revision += [
+ o for o in all_std_attr_objects
+ if ('description' not in o._sa_instance_state.unmodified and
+ o.id not in std_attr_ids)]
+
+ return objects_to_bump_revision
+
def bump_revisions(self, session, context, instances):
self._enforce_if_match_constraints(session)
- # bump revision number for any updated objects in the session
+ # bump revision number for updated objects in the session
self._bump_obj_revisions(
session,
- [
- obj for obj in session.dirty
- if isinstance(obj, standard_attr.HasStandardAttributes)]
- )
+ self._get_objects_to_bump_revision(session.dirty))
# see if any created/updated/deleted objects bump the revision
# of another object
diff --git a/neutron/tests/unit/services/revisions/test_revision_plugin.py b/neutron/tests/unit/services/revisions/test_revision_plugin.py
index f3e48b6719..9d7f990125 100644
--- a/neutron/tests/unit/services/revisions/test_revision_plugin.py
+++ b/neutron/tests/unit/services/revisions/test_revision_plugin.py
@@ -178,6 +178,22 @@ class TestRevisionPlugin(test_plugin.Ml2PluginV2TestCase):
new_rev = response['port']['revision_number']
self.assertGreater(new_rev, rev)
+ def test_network_description_bumps_revision(self):
+ with self.network() as net:
+ rev = net['network']['revision_number']
+ data = {'network': {'description': 'Test Description'}}
+ response = self._update('networks', net['network']['id'], data)
+ new_rev = response['network']['revision_number']
+ self.assertEqual(rev + 1, new_rev)
+
+ def test_subnet_description_bumps_revision(self):
+ with self.subnet() as subnet:
+ rev = subnet['subnet']['revision_number']
+ data = {'subnet': {'description': 'Test Description'}}
+ response = self._update('subnets', subnet['subnet']['id'], data)
+ new_rev = response['subnet']['revision_number']
+ self.assertEqual(rev + 1, new_rev)
+
def test_security_group_rule_ops_bump_security_group(self):
s = {'security_group': {'tenant_id': 'some_tenant', 'name': '',
'description': 's'}}