From 1145a9899de4efeda3eb53c1be709584ccf5f39b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Dulko?= Date: Thu, 19 Nov 2015 17:50:20 +0100 Subject: [PATCH] Recognize extra fields in CinderObjectDictCompat We're still in the process of transitioning to the object notation in a lot of places and that's why we've decided to keep specialized get in CinderObjectDictCompat. This one wasn't looking at aliases (properties) from obj_extra_fields. This commit fixes that and adds a unit test for this method. We should eventually stop using it, but for Mitaka this will make a lot of things easier. Change-Id: I1df610bedffdeae56444ce0a40f8fb48216e91b7 Related-Bug: 1516903 --- cinder/objects/base.py | 7 +++++++ cinder/tests/unit/objects/test_base.py | 28 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/cinder/objects/base.py b/cinder/objects/base.py index efa1293f8..61498370d 100644 --- a/cinder/objects/base.py +++ b/cinder/objects/base.py @@ -240,6 +240,13 @@ class CinderObjectDictCompat(base.VersionedObjectDictCompat): else: return getattr(self, key) + def __contains__(self, name): + try: + # Overriding this to make extra fields pass "'foo' in obj" tests + return name in self.obj_extra_fields or self.obj_attr_is_set(name) + except AttributeError: + return False + class CinderPersistentObject(object): """Mixin class for Persistent objects. diff --git a/cinder/tests/unit/objects/test_base.py b/cinder/tests/unit/objects/test_base.py index ec12ab6b8..6e95124c3 100644 --- a/cinder/tests/unit/objects/test_base.py +++ b/cinder/tests/unit/objects/test_base.py @@ -538,3 +538,31 @@ class TestCinderObjectConditionalUpdate(test.TestCase): # Check that the volume in the DB has also been updated self._check_volume(volume, 'deleting', expected_size, True) + + +class TestCinderDictObject(test_objects.BaseObjectsTestCase): + @objects.base.CinderObjectRegistry.register_if(False) + class TestDictObject(objects.base.CinderObjectDictCompat, + objects.base.CinderObject): + obj_extra_fields = ['foo'] + + fields = { + 'abc': fields.StringField(nullable=True), + 'def': fields.IntegerField(nullable=True), + } + + @property + def foo(self): + return 42 + + def test_dict_objects(self): + obj = self.TestDictObject() + self.assertIsNone(obj.get('non_existing')) + self.assertEqual('val', obj.get('abc', 'val')) + obj.abc = 'val2' + self.assertEqual('val2', obj.get('abc', 'val')) + self.assertEqual(42, obj.get('foo')) + + self.assertTrue('foo' in obj) + self.assertTrue('abc' in obj) + self.assertFalse('def' in obj) -- 2.45.2