Merge "Add backref relationships to ConsistencyGroup obj"

This commit is contained in:
Jenkins 2015-12-31 20:06:56 +00:00 committed by Gerrit Code Review
commit c2315085e8
5 changed files with 126 additions and 4 deletions

View File

@ -25,8 +25,8 @@ def register_all():
# function in order for it to be registered by services that may
# need to receive it via RPC.
__import__('cinder.objects.backup')
__import__('cinder.objects.consistencygroup')
__import__('cinder.objects.cgsnapshot')
__import__('cinder.objects.consistencygroup')
__import__('cinder.objects.service')
__import__('cinder.objects.snapshot')
__import__('cinder.objects.volume')

View File

@ -19,11 +19,15 @@ from cinder import objects
from cinder.objects import base
from oslo_versionedobjects import fields
OPTIONAL_FIELDS = ['cgsnapshots', 'volumes']
@base.CinderObjectRegistry.register
class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
base.CinderObjectDictCompat):
VERSION = '1.0'
# Version 1.0: Initial version
# Version 1.1: Added cgsnapshots and volumes relationships
VERSION = '1.1'
fields = {
'id': fields.UUIDField(),
@ -37,14 +41,35 @@ class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
'status': fields.StringField(nullable=True),
'cgsnapshot_id': fields.UUIDField(nullable=True),
'source_cgid': fields.UUIDField(nullable=True),
'cgsnapshots': fields.ObjectField('CGSnapshotList', nullable=True),
'volumes': fields.ObjectField('VolumeList', nullable=True),
}
@staticmethod
def _from_db_object(context, consistencygroup, db_consistencygroup):
def _from_db_object(context, consistencygroup, db_consistencygroup,
expected_attrs=None):
if expected_attrs is None:
expected_attrs = []
for name, field in consistencygroup.fields.items():
if name in OPTIONAL_FIELDS:
continue
value = db_consistencygroup.get(name)
setattr(consistencygroup, name, value)
if 'cgsnapshots' in expected_attrs:
cgsnapshots = base.obj_make_list(
context, objects.CGSnapshotsList(context),
objects.CGSnapshot,
db_consistencygroup['cgsnapshots'])
consistencygroup.cgsnapshots = cgsnapshots
if 'volumes' in expected_attrs:
volumes = base.obj_make_list(
context, objects.VolumeList(context),
objects.Volume,
db_consistencygroup['volumes'])
consistencygroup.cgsnapshots = volumes
consistencygroup._context = context
consistencygroup.obj_reset_changes()
return consistencygroup
@ -55,14 +80,49 @@ class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
raise exception.ObjectActionError(action='create',
reason=_('already_created'))
updates = self.cinder_obj_get_changes()
if 'cgsnapshots' in updates:
raise exception.ObjectActionError(action='create',
reason=_('cgsnapshots assigned'))
if 'volumes' in updates:
raise exception.ObjectActionError(action='create',
reason=_('volumes assigned'))
db_consistencygroups = db.consistencygroup_create(self._context,
updates)
self._from_db_object(self._context, self, db_consistencygroups)
def obj_load_attr(self, attrname):
if attrname not in OPTIONAL_FIELDS:
raise exception.ObjectActionError(
action='obj_load_attr',
reason=_('attribute %s not lazy-loadable') % attrname)
if not self._context:
raise exception.OrphanedObjectError(method='obj_load_attr',
objtype=self.obj_name())
if attrname == 'cgsnapshots':
self.cgsnapshots = objects.CGSnapshotList.get_all_by_group(
self._context, self.id)
if attrname == 'volumes':
self.volumes = objects.VolumeList.get_all_by_group(self._context,
self.id)
self.obj_reset_changes(fields=[attrname])
@base.remotable
def save(self):
updates = self.cinder_obj_get_changes()
if updates:
if 'cgsnapshots' in updates:
raise exception.ObjectActionError(
action='save', reason=_('cgsnapshots changed'))
if 'volumes' in updates:
raise exception.ObjectActionError(
action='save', reason=_('volumes changed'))
db.consistencygroup_update(self._context, self.id, updates)
self.obj_reset_changes()

View File

@ -23,6 +23,7 @@ def fake_db_consistencygroup(**updates):
'user_id': '2',
'project_id': '3',
'host': 'FakeHost',
'volumes': [],
}
for name, field in objects.ConsistencyGroup.fields.items():
if name in db_values:

View File

@ -32,6 +32,16 @@ fake_consistencygroup = {
'source_cgid': None,
}
fake_cgsnapshot = {
'id': '1',
'user_id': 'fake_user_id',
'project_id': 'fake_project_id',
'name': 'fake_name',
'description': 'fake_description',
'status': 'creating',
'consistencygroup_id': 'fake_id',
}
class TestConsistencyGroup(test_objects.BaseObjectsTestCase):
@ -74,6 +84,57 @@ class TestConsistencyGroup(test_objects.BaseObjectsTestCase):
consistencygroup.id,
{'status': 'active'})
def test_save_with_cgsnapshots(self):
consistencygroup = objects.ConsistencyGroup._from_db_object(
self.context, objects.ConsistencyGroup(), fake_consistencygroup)
cgsnapshots_objs = [objects.CGSnapshot(context=self.context, id=i)
for i in [3, 4, 5]]
cgsnapshots = objects.CGSnapshotList(objects=cgsnapshots_objs)
consistencygroup.name = 'foobar'
consistencygroup.cgsnapshots = cgsnapshots
self.assertEqual({'name': 'foobar',
'cgsnapshots': cgsnapshots},
consistencygroup.obj_get_changes())
self.assertRaises(exception.ObjectActionError, consistencygroup.save)
def test_save_with_volumes(self):
consistencygroup = objects.ConsistencyGroup._from_db_object(
self.context, objects.ConsistencyGroup(), fake_consistencygroup)
volumes_objs = [objects.Volume(context=self.context, id=i)
for i in [3, 4, 5]]
volumes = objects.VolumeList(objects=volumes_objs)
consistencygroup.name = 'foobar'
consistencygroup.volumes = volumes
self.assertEqual({'name': 'foobar',
'volumes': volumes},
consistencygroup.obj_get_changes())
self.assertRaises(exception.ObjectActionError, consistencygroup.save)
@mock.patch('cinder.objects.cgsnapshot.CGSnapshotList.get_all_by_group')
@mock.patch('cinder.objects.volume.VolumeList.get_all_by_group')
def test_obj_load_attr(self, mock_vol_get_all_by_group,
mock_cgsnap_get_all_by_group):
consistencygroup = objects.ConsistencyGroup._from_db_object(
self.context, objects.ConsistencyGroup(), fake_consistencygroup)
# Test cgsnapshots lazy-loaded field
cgsnapshots_objs = [objects.CGSnapshot(context=self.context, id=i)
for i in [3, 4, 5]]
cgsnapshots = objects.CGSnapshotList(context=self.context,
objects=cgsnapshots_objs)
mock_cgsnap_get_all_by_group.return_value = cgsnapshots
self.assertEqual(cgsnapshots, consistencygroup.cgsnapshots)
mock_cgsnap_get_all_by_group.assert_called_once_with(
self.context, consistencygroup.id)
# Test volumes lazy-loaded field
volume_objs = [objects.Volume(context=self.context, id=i)
for i in [3, 4, 5]]
volumes = objects.VolumeList(context=self.context, objects=volume_objs)
mock_vol_get_all_by_group.return_value = volumes
self.assertEqual(volumes, consistencygroup.volumes)
mock_vol_get_all_by_group.assert_called_once_with(self.context,
consistencygroup.id)
@mock.patch('cinder.db.consistencygroup_destroy')
def test_destroy(self, consistencygroup_destroy):
consistencygroup = objects.ConsistencyGroup(context=self.context,

View File

@ -26,7 +26,7 @@ object_data = {
'BackupList': '1.0-24591dabe26d920ce0756fe64cd5f3aa',
'CGSnapshot': '1.0-190da2a2aa9457edc771d888f7d225c4',
'CGSnapshotList': '1.0-e8c3f4078cd0ee23487b34d173eec776',
'ConsistencyGroup': '1.0-b9bad093daee0b259edddb3993c60c31',
'ConsistencyGroup': '1.1-8d8b867a67c1bd6e9f840bcf5e375dbb',
'ConsistencyGroupList': '1.0-09d0aad5491e762ecfdf66bef02ceb8d',
'Service': '1.0-64baeb4911dbab1153064dd1c87edb9f',
'ServiceList': '1.0-d242d3384b68e5a5a534e090ff1d5161',