Make instance object tolerate isotime strings

Any time we get a db object over RPC, the datetime has been
serialized to an isotime string. We have other legacy code that
needs to tolerate this, and those hacks would need to be
replicated in the objects transition. Instead, make the instance
object type function tolerate isotime-formatted strings so that
we can more easily convert RPC-transited database objects
until we're fully converted, at which time we could remove the
tolerance. Luckily, the objects still end up with a datetime
internally, which means the rest of the code can stop needing to
handle strings and datetimes gracefully.

Related to blueprint unified-object-model

Change-Id: I132559d3541d19353de6acc36a2740185e564105
This commit is contained in:
Dan Smith
2013-06-03 09:41:01 -07:00
parent 275e673e90
commit 8201359331
4 changed files with 22 additions and 6 deletions

View File

@@ -168,9 +168,9 @@ class NovaObject(object):
# by subclasses, but that is a special case. Objects inheriting from
# other objects will not receive this merging of fields contents.
fields = {
'created_at': obj_utils.datetime_or_none,
'updated_at': obj_utils.datetime_or_none,
'deleted_at': obj_utils.datetime_or_none,
'created_at': obj_utils.datetime_or_str_or_none,
'updated_at': obj_utils.datetime_or_str_or_none,
'deleted_at': obj_utils.datetime_or_str_or_none,
}
def __init__(self):

View File

@@ -58,9 +58,9 @@ class Instance(base.NovaObject):
'reservation_id': obj_utils.str_or_none,
'scheduled_at': obj_utils.datetime_or_none,
'launched_at': obj_utils.datetime_or_none,
'terminated_at': obj_utils.datetime_or_none,
'scheduled_at': obj_utils.datetime_or_str_or_none,
'launched_at': obj_utils.datetime_or_str_or_none,
'terminated_at': obj_utils.datetime_or_str_or_none,
'availability_zone': obj_utils.str_or_none,

View File

@@ -27,6 +27,14 @@ def datetime_or_none(dt):
raise ValueError('A datetime.datetime is required here')
# NOTE(danms): Being tolerant of isotime strings here will help us
# during our objects transition
def datetime_or_str_or_none(val):
if isinstance(val, basestring):
return timeutils.parse_isotime(val)
return datetime_or_none(val)
def int_or_none(val):
"""Attempt to parse an integer value, or None."""
if val is None:

View File

@@ -123,6 +123,14 @@ class TestUtils(test.TestCase):
self.assertEqual(utils.datetime_or_none(None), None)
self.assertRaises(ValueError, utils.datetime_or_none, 'foo')
def test_datetime_or_str_or_none(self):
dts = timeutils.isotime()
dt = timeutils.parse_isotime(dts)
self.assertEqual(utils.datetime_or_str_or_none(dt), dt)
self.assertEqual(utils.datetime_or_str_or_none(None), None)
self.assertEqual(utils.datetime_or_str_or_none(dts), dt)
self.assertRaises(ValueError, utils.datetime_or_str_or_none, 'foo')
def test_int_or_none(self):
self.assertEqual(utils.int_or_none(1), 1)
self.assertEqual(utils.int_or_none('1'), 1)