Fix self.fields on API Chassis object

All fields from objects.Chassis were being added to self.fields in
the API Chassis object. Because of this, when someone would POST,
there'd be an entry for {'id': None} in the dictionary passed to
dbapi.create_chassis(). We should only set fields we're exposing.

This also required fixing PATCH to not try to look at fields not set on
the API Chassis object when mapping to objects.Chassis.

Change-Id: Ie5b31455b925ae395995de7b7c638ab5e3543633
This commit is contained in:
Lucas Alvares Gomes 2014-08-05 16:13:11 +01:00
parent fb0aaca6e6
commit c95bba10f5
2 changed files with 25 additions and 5 deletions

View File

@ -60,9 +60,13 @@ class Chassis(base.APIBase):
"Links to the collection of nodes contained in this chassis"
def __init__(self, **kwargs):
self.fields = objects.Chassis.fields.keys()
for k in self.fields:
setattr(self, k, kwargs.get(k))
self.fields = []
for field in objects.Chassis.fields:
# Skip fields we do not expose.
if not hasattr(self, field):
continue
self.fields.append(field)
setattr(self, field, kwargs.get(field))
@classmethod
def _convert_with_links(cls, chassis, url, expand=True):
@ -232,8 +236,13 @@ class ChassisController(rest.RestController):
# Update only the fields that have changed
for field in objects.Chassis.fields:
if rpc_chassis[field] != getattr(chassis, field):
rpc_chassis[field] = getattr(chassis, field)
try:
patch_val = getattr(chassis, field)
except AttributeError:
# Ignore fields that aren't exposed in the API
continue
if rpc_chassis[field] != patch_val:
rpc_chassis[field] = patch_val
rpc_chassis.save()
return Chassis.convert_with_links(rpc_chassis)

View File

@ -329,6 +329,17 @@ class TestPost(base.FunctionalTest):
self.assertEqual(urlparse.urlparse(response.location).path,
expected_location)
def test_create_chassis_doesnt_contain_id(self):
with mock.patch.object(self.dbapi, 'create_chassis',
wraps=self.dbapi.create_chassis) as cc_mock:
cdict = apiutils.chassis_post_data(extra={'foo': 123})
self.post_json('/chassis', cdict)
result = self.get_json('/chassis/%s' % cdict['uuid'])
self.assertEqual(cdict['extra'], result['extra'])
cc_mock.assert_called_once_with(mock.ANY)
# Check that 'id' is not in first arg of positional args
self.assertNotIn('id', cc_mock.call_args[0][0])
def test_create_chassis_generate_uuid(self):
cdict = apiutils.chassis_post_data()
del cdict['uuid']