objects: in get_object(s), filter by fields, not model attributes
This is needed for objects that have fields that have different names comparing to corresponding attributes in the database. Updated test cases to reflect that behaviour (pass field filters into object get_object(s), but expect db_api functions to receive and return model attributes). Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db Change-Id: Ib65922eeaa9573312e3428c748ff415ef600052c
This commit is contained in:
parent
9e7137f7f6
commit
d4012705de
|
@ -276,7 +276,10 @@ class NeutronDbObject(NeutronObject):
|
|||
missing_keys=missing_keys)
|
||||
|
||||
with db_api.autonested_transaction(context.session):
|
||||
db_obj = obj_db_api.get_object(context, cls.db_model, **kwargs)
|
||||
db_obj = obj_db_api.get_object(
|
||||
context, cls.db_model,
|
||||
**cls.modify_fields_to_db(kwargs)
|
||||
)
|
||||
if db_obj:
|
||||
return cls._load_object(context, db_obj)
|
||||
|
||||
|
@ -294,7 +297,9 @@ class NeutronDbObject(NeutronObject):
|
|||
cls.validate_filters(**kwargs)
|
||||
with db_api.autonested_transaction(context.session):
|
||||
db_objs = obj_db_api.get_objects(
|
||||
context, cls.db_model, _pager=_pager, **kwargs)
|
||||
context, cls.db_model, _pager=_pager,
|
||||
**cls.modify_fields_to_db(kwargs)
|
||||
)
|
||||
return [cls._load_object(context, db_obj) for db_obj in db_objs]
|
||||
|
||||
@classmethod
|
||||
|
@ -371,7 +376,7 @@ class NeutronDbObject(NeutronObject):
|
|||
keys = {}
|
||||
for key in self.primary_keys:
|
||||
keys[key] = getattr(self, key)
|
||||
return self.modify_fields_to_db(keys)
|
||||
return keys
|
||||
|
||||
def update_nonidentifying_fields(self, obj_data, reset_changes=False):
|
||||
"""Updates non-identifying fields of an object.
|
||||
|
@ -400,9 +405,11 @@ class NeutronDbObject(NeutronObject):
|
|||
db_obj = obj_db_api.update_object(
|
||||
self.obj_context, self.db_model,
|
||||
self.modify_fields_to_db(updates),
|
||||
**self._get_composite_keys())
|
||||
**self.modify_fields_to_db(
|
||||
self._get_composite_keys()))
|
||||
self.from_db_object(db_obj)
|
||||
|
||||
def delete(self):
|
||||
obj_db_api.delete_object(self.obj_context, self.db_model,
|
||||
**self._get_composite_keys())
|
||||
**self.modify_fields_to_db(
|
||||
self._get_composite_keys()))
|
||||
|
|
|
@ -36,8 +36,9 @@ class AllowedAddressPair(base.NeutronDbObject):
|
|||
|
||||
# TODO(mhickey): get rid of it once we switch the db model to using
|
||||
# custom types.
|
||||
def modify_fields_to_db(self, fields):
|
||||
result = super(AllowedAddressPair, self).modify_fields_to_db(fields)
|
||||
@classmethod
|
||||
def modify_fields_to_db(cls, fields):
|
||||
result = super(AllowedAddressPair, cls).modify_fields_to_db(fields)
|
||||
if 'ip_address' in result:
|
||||
result['ip_address'] = str(result['ip_address'])
|
||||
if 'mac_address' in result:
|
||||
|
|
|
@ -63,12 +63,13 @@ class SubnetPool(base.NeutronDbObject):
|
|||
]
|
||||
return fields
|
||||
|
||||
def modify_fields_to_db(self, fields):
|
||||
result = super(SubnetPool, self).modify_fields_to_db(fields)
|
||||
@classmethod
|
||||
def modify_fields_to_db(cls, fields):
|
||||
result = super(SubnetPool, cls).modify_fields_to_db(fields)
|
||||
if 'prefixes' in result:
|
||||
result['prefixes'] = [
|
||||
models.SubnetPoolPrefix(cidr=str(prefix),
|
||||
subnetpool_id=self.id)
|
||||
subnetpool_id=result['id'])
|
||||
for prefix in result['prefixes']
|
||||
]
|
||||
return result
|
||||
|
@ -152,8 +153,9 @@ class SubnetPoolPrefix(base.NeutronDbObject):
|
|||
|
||||
# TODO(ihrachys): get rid of it once we switch the db model to using CIDR
|
||||
# custom type
|
||||
def modify_fields_to_db(self, fields):
|
||||
result = super(SubnetPoolPrefix, self).modify_fields_to_db(fields)
|
||||
@classmethod
|
||||
def modify_fields_to_db(cls, fields):
|
||||
result = super(SubnetPoolPrefix, cls).modify_fields_to_db(fields)
|
||||
if 'cidr' in result:
|
||||
result['cidr'] = str(result['cidr'])
|
||||
return result
|
||||
|
|
|
@ -310,8 +310,7 @@ class _BaseObjectTestCase(object):
|
|||
if field not in obj_cls.synthetic_fields:
|
||||
generator = FIELD_TYPE_VALUE_GENERATOR_MAP[type(field_obj)]
|
||||
fields[field] = get_value(generator, ip_version)
|
||||
obj = obj_cls(None, **fields)
|
||||
return obj.modify_fields_to_db(fields)
|
||||
return obj_cls.modify_fields_to_db(fields)
|
||||
|
||||
@classmethod
|
||||
def generate_object_keys(cls, obj_cls):
|
||||
|
@ -350,7 +349,8 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
|||
self.assertTrue(self._is_test_class(obj))
|
||||
self.assertEqual(self.obj_fields[0], get_obj_db_fields(obj))
|
||||
get_object_mock.assert_called_once_with(
|
||||
self.context, self._test_class.db_model, **obj_keys)
|
||||
self.context, self._test_class.db_model,
|
||||
**self._test_class.modify_fields_to_db(obj_keys))
|
||||
|
||||
def test_get_object_missing_object(self):
|
||||
with mock.patch.object(obj_db_api, 'get_object', return_value=None):
|
||||
|
@ -403,8 +403,10 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
|||
self._validate_objects(self.db_objs, objs)
|
||||
|
||||
mock_calls = [
|
||||
mock.call(self.context, self._test_class.db_model, _pager=None,
|
||||
**self.valid_field_filter)
|
||||
mock.call(
|
||||
self.context, self._test_class.db_model, _pager=None,
|
||||
**self._test_class.modify_fields_to_db(self.valid_field_filter)
|
||||
)
|
||||
]
|
||||
mock_calls.extend(self._get_synthetic_fields_get_objects_calls(
|
||||
[self.db_obj]))
|
||||
|
@ -519,7 +521,8 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
|||
|
||||
@mock.patch.object(obj_db_api, 'update_object')
|
||||
def test_update_changes(self, update_mock):
|
||||
fields_to_update = self.get_updatable_fields(self.db_obj)
|
||||
fields_to_update = self.get_updatable_fields(
|
||||
self._test_class.modify_fields_from_db(self.db_obj))
|
||||
if not fields_to_update:
|
||||
self.skipTest('No updatable fields found in test class %r' %
|
||||
self._test_class)
|
||||
|
@ -532,13 +535,15 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
|||
obj = self._test_class(self.context, **self.obj_fields[0])
|
||||
# get new values and fix keys
|
||||
update_mock.return_value = self.db_objs[1].copy()
|
||||
for key, value in obj._get_composite_keys().items():
|
||||
fixed_keys = self._test_class.modify_fields_to_db(
|
||||
obj._get_composite_keys())
|
||||
for key, value in fixed_keys.items():
|
||||
update_mock.return_value[key] = value
|
||||
obj.update()
|
||||
update_mock.assert_called_once_with(
|
||||
self.context, self._test_class.db_model,
|
||||
fields_to_update,
|
||||
**obj._get_composite_keys())
|
||||
self._test_class.modify_fields_to_db(fields_to_update),
|
||||
**fixed_keys)
|
||||
|
||||
@mock.patch.object(base.NeutronDbObject,
|
||||
'_get_changed_persistent_fields',
|
||||
|
@ -580,7 +585,7 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
|||
self._check_equal(obj, self.obj_fields[0])
|
||||
delete_mock.assert_called_once_with(
|
||||
self.context, self._test_class.db_model,
|
||||
**obj._get_composite_keys())
|
||||
**self._test_class.modify_fields_to_db(obj._get_composite_keys()))
|
||||
|
||||
@mock.patch(OBJECTS_BASE_OBJ_FROM_PRIMITIVE)
|
||||
def test_clean_obj_from_primitive(self, get_prim_m):
|
||||
|
|
Loading…
Reference in New Issue