Use wsme.Unset as default value for API objects

wsme.Unset should be used instead of None as default value for API
objects as None is valid value that could be passed to constructor.

Closes-bug: #1385247
Change-Id: I94f6dd14a7befe217552cf2c6998bb1c1d2d338d
This commit is contained in:
Vladyslav Drok 2014-10-27 15:09:45 +02:00
parent 9cee24e257
commit 645072bfa3
6 changed files with 65 additions and 23 deletions

View File

@ -66,7 +66,7 @@ class Chassis(base.APIBase):
if not hasattr(self, field):
continue
self.fields.append(field)
setattr(self, field, kwargs.get(field))
setattr(self, field, kwargs.get(field, wtypes.Unset))
@classmethod
def _convert_with_links(cls, chassis, url, expand=True):
@ -244,6 +244,8 @@ class ChassisController(rest.RestController):
except AttributeError:
# Ignore fields that aren't exposed in the API
continue
if patch_val == wtypes.Unset:
patch_val = None
if rpc_chassis[field] != patch_val:
rpc_chassis[field] = patch_val

View File

@ -442,7 +442,7 @@ class Node(base.APIBase):
def __init__(self, **kwargs):
self.fields = []
fields = objects.Node.fields.keys()
fields = list(objects.Node.fields)
# NOTE(lucasagomes): chassis_uuid is not part of objects.Node.fields
# because it's an API-only attribute.
fields.append('chassis_uuid')
@ -451,14 +451,14 @@ class Node(base.APIBase):
if not hasattr(self, k):
continue
self.fields.append(k)
setattr(self, k, kwargs.get(k))
setattr(self, k, kwargs.get(k, wtypes.Unset))
# NOTE(lucasagomes): chassis_id is an attribute created on-the-fly
# by _set_chassis_uuid(), it needs to be present in the fields so
# that as_dict() will contain chassis_id field when converting it
# before saving it in the database.
self.fields.append('chassis_id')
setattr(self, 'chassis_uuid', kwargs.get('chassis_id'))
setattr(self, 'chassis_uuid', kwargs.get('chassis_id', wtypes.Unset))
@classmethod
def _convert_with_links(cls, node, url, expand=True):
@ -841,6 +841,8 @@ class NodesController(rest.RestController):
except AttributeError:
# Ignore fields that aren't exposed in the API
continue
if patch_val == wtypes.Unset:
patch_val = None
if rpc_node[field] != patch_val:
rpc_node[field] = patch_val

View File

@ -89,7 +89,7 @@ class Port(base.APIBase):
def __init__(self, **kwargs):
self.fields = []
fields = list(objects.Port.fields.keys())
fields = list(objects.Port.fields)
# NOTE(lucasagomes): node_uuid is not part of objects.Port.fields
# because it's an API-only attribute
fields.append('node_uuid')
@ -98,14 +98,14 @@ class Port(base.APIBase):
if not hasattr(self, field):
continue
self.fields.append(field)
setattr(self, field, kwargs.get(field))
setattr(self, field, kwargs.get(field, wtypes.Unset))
# NOTE(lucasagomes): node_id is an attribute created on-the-fly
# by _set_node_uuid(), it needs to be present in the fields so
# that as_dict() will contain node_id field when converting it
# before saving it in the database.
self.fields.append('node_id')
setattr(self, 'node_uuid', kwargs.get('node_id'))
setattr(self, 'node_uuid', kwargs.get('node_id', wtypes.Unset))
@classmethod
def _convert_with_links(cls, port, url, expand=True):
@ -329,6 +329,8 @@ class PortsController(rest.RestController):
except AttributeError:
# Ignore fields that aren't exposed in the API
continue
if patch_val == wtypes.Unset:
patch_val = None
if rpc_port[field] != patch_val:
rpc_port[field] = patch_val

View File

@ -21,14 +21,26 @@ import mock
from oslo.config import cfg
from oslo.utils import timeutils
from six.moves.urllib import parse as urlparse
from wsme import types as wtypes
from ironic.api.controllers.v1 import chassis as api_chassis
from ironic.common import utils
from ironic.tests.api import base
from ironic.tests.api import base as api_base
from ironic.tests.api import utils as apiutils
from ironic.tests import base
from ironic.tests.objects import utils as obj_utils
class TestListChassis(base.FunctionalTest):
class TestChassisObject(base.TestCase):
def test_chassis_init(self):
chassis_dict = apiutils.chassis_post_data()
del chassis_dict['description']
chassis = api_chassis.Chassis(**chassis_dict)
self.assertEqual(wtypes.Unset, chassis.description)
class TestListChassis(api_base.FunctionalTest):
def test_empty(self):
data = self.get_json('/chassis')
@ -137,7 +149,7 @@ class TestListChassis(base.FunctionalTest):
self.assertEqual(404, response.status_int)
class TestPatch(base.FunctionalTest):
class TestPatch(api_base.FunctionalTest):
def setUp(self):
super(TestPatch, self).setUp()
@ -287,7 +299,7 @@ class TestPatch(base.FunctionalTest):
self.assertTrue(response.json['error_message'])
class TestPost(base.FunctionalTest):
class TestPost(api_base.FunctionalTest):
@mock.patch.object(timeutils, 'utcnow')
def test_create_chassis(self, mock_utcnow):
@ -358,7 +370,7 @@ class TestPost(base.FunctionalTest):
self.assertEqual(descr, result['description'])
class TestDelete(base.FunctionalTest):
class TestDelete(api_base.FunctionalTest):
def test_delete_chassis(self):
chassis = obj_utils.create_test_chassis(self.context)

View File

@ -22,15 +22,18 @@ from oslo.config import cfg
from oslo.utils import timeutils
from six.moves.urllib import parse as urlparse
from testtools.matchers import HasLength
from wsme import types as wtypes
from ironic.api.controllers.v1 import node as api_node
from ironic.common import boot_devices
from ironic.common import exception
from ironic.common import states
from ironic.common import utils
from ironic.conductor import rpcapi
from ironic import objects
from ironic.tests.api import base
from ironic.tests.api import base as api_base
from ironic.tests.api import utils as apiutils
from ironic.tests import base
from ironic.tests.db import utils as dbutils
from ironic.tests.objects import utils as obj_utils
@ -45,7 +48,16 @@ def post_get_test_node(**kw):
return node
class TestListNodes(base.FunctionalTest):
class TestNodeObject(base.TestCase):
def test_node_init(self):
node_dict = apiutils.node_post_data(chassis_id=None)
del node_dict['instance_uuid']
node = api_node.Node(**node_dict)
self.assertEqual(wtypes.Unset, node.instance_uuid)
class TestListNodes(api_base.FunctionalTest):
def setUp(self):
super(TestListNodes, self).setUp()
@ -473,7 +485,7 @@ class TestListNodes(base.FunctionalTest):
mock_gsbd.assert_called_once_with(mock.ANY, node.uuid, 'test-topic')
class TestPatch(base.FunctionalTest):
class TestPatch(api_base.FunctionalTest):
def setUp(self):
super(TestPatch, self).setUp()
@ -752,7 +764,7 @@ class TestPatch(base.FunctionalTest):
self.assertTrue(response.json['error_message'])
class TestPost(base.FunctionalTest):
class TestPost(api_base.FunctionalTest):
def setUp(self):
super(TestPost, self).setUp()
@ -916,7 +928,7 @@ class TestPost(base.FunctionalTest):
self.assertTrue(response.json['error_message'])
class TestDelete(base.FunctionalTest):
class TestDelete(api_base.FunctionalTest):
def setUp(self):
super(TestDelete, self).setUp()
@ -977,7 +989,7 @@ class TestDelete(base.FunctionalTest):
topic='test-topic')
class TestPut(base.FunctionalTest):
class TestPut(api_base.FunctionalTest):
def setUp(self):
super(TestPut, self).setUp()

View File

@ -22,12 +22,15 @@ from oslo.config import cfg
from oslo.utils import timeutils
from six.moves.urllib import parse as urlparse
from testtools.matchers import HasLength
from wsme import types as wtypes
from ironic.api.controllers.v1 import port as api_port
from ironic.common import exception
from ironic.common import utils
from ironic.conductor import rpcapi
from ironic.tests.api import base
from ironic.tests.api import base as api_base
from ironic.tests.api import utils as apiutils
from ironic.tests import base
from ironic.tests.db import utils as dbutils
from ironic.tests.objects import utils as obj_utils
@ -42,7 +45,16 @@ def post_get_test_port(**kw):
return port
class TestListPorts(base.FunctionalTest):
class TestPortObject(base.TestCase):
def test_port_init(self):
port_dict = apiutils.port_post_data(node_id=None)
del port_dict['extra']
port = api_port.Port(**port_dict)
self.assertEqual(wtypes.Unset, port.extra)
class TestListPorts(api_base.FunctionalTest):
def setUp(self):
super(TestListPorts, self).setUp()
@ -175,7 +187,7 @@ class TestListPorts(base.FunctionalTest):
@mock.patch.object(rpcapi.ConductorAPI, 'update_port')
class TestPatch(base.FunctionalTest):
class TestPatch(api_base.FunctionalTest):
def setUp(self):
super(TestPatch, self).setUp()
@ -475,7 +487,7 @@ class TestPatch(base.FunctionalTest):
self.assertEqual(address.lower(), kargs.address)
class TestPost(base.FunctionalTest):
class TestPost(api_base.FunctionalTest):
def setUp(self):
super(TestPost, self).setUp()
@ -607,7 +619,7 @@ class TestPost(base.FunctionalTest):
self.assertIn(address, error_msg.upper())
class TestDelete(base.FunctionalTest):
class TestDelete(api_base.FunctionalTest):
def setUp(self):
super(TestDelete, self).setUp()