Fix mistakes introduced with QoSSpecs object

If15ea8b628a6f88211a5d5cc7aadff44f7840138 introduced some mistakes that
I was able to identify when rebasing RequestSpec object patch:

* Missing loading volume_types relationship in QualityOfServiceSpecs
  _from_db_object.
* Wrong source of qos_specs relationship in VolumeType _from_db_object.
* Inefficient loading od QoSSpecs associations in db layer.
* Use of self in classmethod.

This commit fixes the issues.

Change-Id: I3b78127791a03e1a35a30d7f84f66e97d89c7cf9
Closes-Bug: 1603472
This commit is contained in:
Michał Dulko 2016-07-15 17:00:57 +02:00
parent cbc5d499bd
commit e1b254dad1
6 changed files with 24 additions and 12 deletions

View File

@ -3089,9 +3089,11 @@ def volume_type_qos_associations_get(context, qos_specs_id, inactive=False):
models.QualityOfServiceSpecs, models.QualityOfServiceSpecs,
qos_specs_id): qos_specs_id):
raise exception.QoSSpecsNotFound(specs_id=qos_specs_id) raise exception.QoSSpecsNotFound(specs_id=qos_specs_id)
return model_query(context, models.VolumeTypes, vts = (model_query(context, models.VolumeTypes, read_deleted=read_deleted).
read_deleted=read_deleted). \ options(joinedload('extra_specs')).
filter_by(qos_specs_id=qos_specs_id).all() options(joinedload('projects')).
filter_by(qos_specs_id=qos_specs_id).all())
return vts
@require_admin_context @require_admin_context

View File

@ -113,7 +113,10 @@ class QualityOfServiceSpecs(base.CinderPersistentObject,
self._context, self.id) self._context, self.id)
@staticmethod @staticmethod
def _from_db_object(context, qos_spec, db_qos_spec): def _from_db_object(context, qos_spec, db_qos_spec, expected_attrs=None):
if expected_attrs is None:
expected_attrs = []
for name, field in qos_spec.fields.items(): for name, field in qos_spec.fields.items():
if name not in QualityOfServiceSpecs.OPTIONAL_FIELDS: if name not in QualityOfServiceSpecs.OPTIONAL_FIELDS:
value = db_qos_spec.get(name) value = db_qos_spec.get(name)
@ -123,6 +126,11 @@ class QualityOfServiceSpecs(base.CinderPersistentObject,
value = {} value = {}
setattr(qos_spec, name, value) setattr(qos_spec, name, value)
if 'volume_types' in expected_attrs:
volume_types = objects.VolumeTypeList.get_all_types_for_qos(
context, db_qos_spec['id'])
qos_spec.volume_types = volume_types
qos_spec._context = context qos_spec._context = context
qos_spec.obj_reset_changes() qos_spec.obj_reset_changes()
return qos_spec return qos_spec

View File

@ -88,9 +88,7 @@ class VolumeType(base.CinderPersistentObject, base.CinderObject,
type.projects = db_type.get('projects', []) type.projects = db_type.get('projects', [])
if 'qos_specs' in expected_attrs: if 'qos_specs' in expected_attrs:
qos_specs = objects.QualityOfServiceSpecs(context) qos_specs = objects.QualityOfServiceSpecs(context)
qos_specs._from_db_object(context, qos_specs._from_db_object(context, qos_specs, db_type['qos_specs'])
qos_specs,
type['qos_specs'])
type.qos_specs = qos_specs type.qos_specs = qos_specs
type._context = context type._context = context
type.obj_reset_changes() type.obj_reset_changes()
@ -143,7 +141,7 @@ class VolumeTypeList(base.ObjectListBase, base.CinderObject):
expected_attrs=expected_attrs) expected_attrs=expected_attrs)
@classmethod @classmethod
def get_all_types_for_qos(self, context, qos_id): def get_all_types_for_qos(cls, context, qos_id):
types = db.qos_specs_associations_get(context, qos_id) types = db.qos_specs_associations_get(context, qos_id)
return base.obj_make_list(context, self(context), objects.VolumeType, return base.obj_make_list(context, cls(context), objects.VolumeType,
types) types)

View File

@ -231,6 +231,8 @@ class QoSSpecsTestCase(test.TestCase):
} }
self.assertIn(expected_type, res) self.assertIn(expected_type, res)
e = exception.QoSSpecsNotFound(specs_id='Trouble')
mock_qos_specs_associations_get.side_effect = e
self.assertRaises(exception.CinderException, self.assertRaises(exception.CinderException,
qos_specs.get_associations, self.ctxt, qos_specs.get_associations, self.ctxt,
'Trouble') 'Trouble')

View File

@ -135,8 +135,8 @@ def delete_keys(context, qos_specs_id, keys):
def get_associations(context, qos_specs_id): def get_associations(context, qos_specs_id):
"""Get all associations of given qos specs.""" """Get all associations of given qos specs."""
try: try:
qos_spec = objects.QualityOfServiceSpecs.get_by_id( types = objects.VolumeTypeList.get_all_types_for_qos(context,
context, qos_specs_id) qos_specs_id)
except db_exc.DBError: except db_exc.DBError:
LOG.exception(_LE('DB error:')) LOG.exception(_LE('DB error:'))
msg = _('Failed to get all associations of ' msg = _('Failed to get all associations of '
@ -145,7 +145,7 @@ def get_associations(context, qos_specs_id):
raise exception.CinderException(message=msg) raise exception.CinderException(message=msg)
result = [] result = []
for vol_type in qos_spec.volume_types: for vol_type in types:
result.append({ result.append({
'association_type': 'volume_type', 'association_type': 'volume_type',
'name': vol_type.name, 'name': vol_type.name,

View File

@ -95,6 +95,8 @@ objects_ignore_messages = [
"Module 'cinder.objects' has no 'SnapshotList' member", "Module 'cinder.objects' has no 'SnapshotList' member",
"Module 'cinder.objects' has no 'Volume' member", "Module 'cinder.objects' has no 'Volume' member",
"Module 'cinder.objects' has no 'VolumeList' member", "Module 'cinder.objects' has no 'VolumeList' member",
"Module 'cinder.objects' has no 'VolumeType' member",
"Module 'cinder.objects' has no 'VolumeTypeList' member",
] ]
objects_ignore_modules = ["cinder/objects/"] objects_ignore_modules = ["cinder/objects/"]