Make objects serialize_args() handle datetimes in positional args
Remotable methods in a new TaskLog object need to serialize datatimes passed as positional args. Right now the serialize_args() decorator only look at kwargs. In addition, serialization of datetimes need to use timeutils.strtime() to match the deserialization code in the db api. Also makes this change for serialization of kwargs to partially solve a bug with how this decorator is used in the BandwidthUsage object. A follow-up patch closes the bug by adding conversion back to datetimes using existing db api helper method convert_objects_related_datetimes(), which in turn makes use of timeutils.parse_strtime(). Related to blueprint liberty-objects Change-Id: Ia87be4fd37bee499510ae543e11029c2013d4905 Related-Bug: #1442795
This commit is contained in:
parent
dde1c1e175
commit
83cdec4123
@ -938,15 +938,15 @@ def obj_make_list(context, list_obj, item_cls, db_list, **extra_args):
|
||||
def serialize_args(fn):
|
||||
"""Decorator that will do the arguments serialization before remoting."""
|
||||
def wrapper(obj, *args, **kwargs):
|
||||
for kw in kwargs:
|
||||
value_arg = kwargs.get(kw)
|
||||
if kw == 'exc_val' and value_arg:
|
||||
kwargs[kw] = str(value_arg)
|
||||
elif kw == 'exc_tb' and (
|
||||
not isinstance(value_arg, six.string_types) and value_arg):
|
||||
kwargs[kw] = ''.join(traceback.format_tb(value_arg))
|
||||
elif isinstance(value_arg, datetime.datetime):
|
||||
kwargs[kw] = timeutils.isotime(value_arg)
|
||||
args = [timeutils.strtime(at=arg) if isinstance(arg, datetime.datetime)
|
||||
else arg for arg in args]
|
||||
for k, v in kwargs.iteritems():
|
||||
if k == 'exc_val' and v:
|
||||
kwargs[k] = str(v)
|
||||
elif k == 'exc_tb' and v and not isinstance(v, six.string_types):
|
||||
kwargs[k] = ''.join(traceback.format_tb(v))
|
||||
elif isinstance(v, datetime.datetime):
|
||||
kwargs[k] = timeutils.strtime(at=v)
|
||||
if hasattr(fn, '__call__'):
|
||||
return fn(obj, *args, **kwargs)
|
||||
# NOTE(danms): We wrap a descriptor, so use that protocol
|
||||
|
@ -1193,6 +1193,28 @@ class TestObjectSerializer(_BaseTestCase):
|
||||
self.assertIsInstance(thing2['foo'], base.NovaObject)
|
||||
|
||||
|
||||
class TestArgsSerializer(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(TestArgsSerializer, self).setUp()
|
||||
self.now = timeutils.utcnow()
|
||||
self.str_now = timeutils.strtime(at=self.now)
|
||||
|
||||
@base.serialize_args
|
||||
def _test_serialize_args(self, *args, **kwargs):
|
||||
expected_args = ('untouched', self.str_now, self.str_now)
|
||||
for index, val in enumerate(args):
|
||||
self.assertEqual(expected_args[index], val)
|
||||
|
||||
expected_kwargs = {'a': 'untouched', 'b': self.str_now,
|
||||
'c': self.str_now}
|
||||
for key, val in kwargs.iteritems():
|
||||
self.assertEqual(expected_kwargs[key], val)
|
||||
|
||||
def test_serialize_args(self):
|
||||
self._test_serialize_args('untouched', self.now, self.now,
|
||||
a='untouched', b=self.now, c=self.now)
|
||||
|
||||
|
||||
# NOTE(danms): The hashes in this list should only be changed if
|
||||
# they come with a corresponding version bump in the affected
|
||||
# objects
|
||||
|
Loading…
Reference in New Issue
Block a user