]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Properly use obj_extra_fields in objects
authorThang Pham <thang.g.pham@gmail.com>
Tue, 17 Mar 2015 14:24:08 +0000 (10:24 -0400)
committerThang Pham <thang.g.pham@gmail.com>
Thu, 26 Mar 2015 19:15:55 +0000 (19:15 +0000)
The following patch fixes a bug in the snapshot object,
where fields that are not part of the Snapshot model,
i.e. name and volume_name, were not specified as
obj_extra_fields in the object. It also fixes the same
problem in the volume object, i.e. name and name_id.
With this patch, those extra fields are properly loaded,
e.g. snapshot.volume_name or volume.name.

Change-Id: Ie2b8dc66c897f89f941e9ad3b80ec4f4ab346430
Closes-Bug: #1429889

cinder/objects/snapshot.py
cinder/objects/volume.py
cinder/tests/objects/test_snapshot.py
cinder/tests/objects/test_volume.py

index 06accd75817e9889f2de0d57b9a26c9d39d940d0..cbf72b61251e71e2c30e1fcaa5a15cd2e05be76a 100644 (file)
@@ -37,8 +37,6 @@ class Snapshot(base.CinderPersistentObject, base.CinderObject,
 
     fields = {
         'id': fields.UUIDField(),
-        'name': fields.StringField(nullable=True),
-        'volume_name': fields.StringField(nullable=True),
 
         'user_id': fields.UUIDField(nullable=True),
         'project_id': fields.UUIDField(nullable=True),
@@ -61,10 +59,18 @@ class Snapshot(base.CinderPersistentObject, base.CinderObject,
         'volume': fields.ObjectField('Volume', nullable=True),
     }
 
+    # NOTE(thangp): obj_extra_fields is used to hold properties that are not
+    # usually part of the model
+    obj_extra_fields = ['name', 'volume_name']
+
     @property
     def name(self):
         return CONF.snapshot_name_template % self.id
 
+    @property
+    def volume_name(self):
+        return self.volume.name
+
     def __init__(self, *args, **kwargs):
         super(Snapshot, self).__init__(*args, **kwargs)
         self._orig_metadata = {}
@@ -167,8 +173,11 @@ class Snapshot(base.CinderPersistentObject, base.CinderObject,
             raise exception.OrphanedObjectError(method='obj_load_attr',
                                                 objtype=self.obj_name())
 
-        self.volume = objects.Volume.get_by_id(self._context, self.volume_id)
-        self.obj_reset_changes(fields=['volume'])
+        if attrname == 'volume':
+            self.volume = objects.Volume.get_by_id(self._context,
+                                                   self.volume_id)
+
+        self.obj_reset_changes(fields=[attrname])
 
     def delete_metadata_key(self, context, key):
         db.snapshot_metadata_delete(context, self.id, key)
index ccc53e93811e56fb86578514cdd904f68ac7279c..8fb2e68b981e009d84ed73abacc2860aa3e71078 100644 (file)
@@ -74,6 +74,10 @@ class Volume(base.CinderPersistentObject, base.CinderObject,
         'replication_driver_data': fields.StringField(nullable=True),
     }
 
+    # NOTE(thangp): obj_extra_fields is used to hold properties that are not
+    # usually part of the model
+    obj_extra_fields = ['name', 'name_id']
+
     @property
     def name_id(self):
         return self.id if not self._name_id else self._name_id
index f5bf7f7c92fb498473be1e13a731422be9d986d4..56d306904495193bf3e92a697f7ad5bf42c59ceb 100644 (file)
@@ -15,6 +15,7 @@
 import mock
 
 from cinder.objects import snapshot as snapshot_obj
+from cinder.objects import volume as volume_obj
 from cinder.tests import fake_volume
 from cinder.tests.objects import test_objects
 
@@ -99,6 +100,24 @@ class TestSnapshot(test_objects._LocalTest):
         snapshot_metadata_delete.assert_called_once_with(self.context, '1',
                                                          'key2')
 
+    def test_obj_fields(self):
+        volume = volume_obj.Volume(context=self.context, id=2, _name_id=2)
+        snapshot = snapshot_obj.Snapshot(context=self.context, id=1,
+                                         volume=volume)
+        self.assertEqual(['name', 'volume_name'], snapshot.obj_extra_fields)
+        self.assertEqual('snapshot-1', snapshot.name)
+        self.assertEqual('volume-2', snapshot.volume_name)
+
+    @mock.patch('cinder.objects.volume.Volume.get_by_id')
+    def test_obj_load_attr(self, volume_get_by_id):
+        snapshot = snapshot_obj.Snapshot._from_db_object(
+            self.context, snapshot_obj.Snapshot(), fake_snapshot)
+        volume = volume_obj.Volume(context=self.context, id=2)
+        volume_get_by_id.return_value = volume
+        self.assertEqual(volume, snapshot.volume)
+        volume_get_by_id.assert_called_once_with(self.context,
+                                                 snapshot.volume_id)
+
 
 class TestSnapshotList(test_objects._LocalTest):
     @mock.patch('cinder.db.snapshot_metadata_get', return_value={})
index 840f30c135fcfe4e0d7a670573c987b4ef1c8d3b..901855a40cb8a9514a79809984cbf036e6b1904a 100644 (file)
@@ -58,6 +58,12 @@ class TestVolume(test_objects._LocalTest):
         volume.destroy()
         volume_destroy.assert_called_once_with(self.context, '1')
 
+    def test_obj_fields(self):
+        volume = objects.Volume(context=self.context, id=2, _name_id=2)
+        self.assertEqual(['name', 'name_id'], volume.obj_extra_fields)
+        self.assertEqual('volume-2', volume.name)
+        self.assertEqual('2', volume.name_id)
+
 
 class TestVolumeList(test_objects._LocalTest):
     @mock.patch('cinder.db.volume_get_all')