diff --git a/nova/objects/base.py b/nova/objects/base.py index 6837066cbddd..ce4df5b512f8 100644 --- a/nova/objects/base.py +++ b/nova/objects/base.py @@ -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 diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py index 13b8dc8ad53a..37be4d29a0ff 100644 --- a/nova/tests/unit/objects/test_objects.py +++ b/nova/tests/unit/objects/test_objects.py @@ -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