Handle string types for InstanceActionEvent exc_tb serialization
Commit 59a6cf233b added code to handle
serializing non-str exception traceback objects, but didn't account for
unicode. This change uses six.string_types to handle str and unicode
objects for the exc_tb argument.
Adds a new unit test for the unicode case and firms up two existing
tests for how traceback.format_tb is mocked (or shouldn't be in the case
of exc_tb being a str).
Closes-Bug: #1327476
Change-Id: Icc10b62a3f65610c50e86c0b366c2b70b1a0932d
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
|
||||
import traceback
|
||||
|
||||
import six
|
||||
|
||||
from nova import db
|
||||
from nova.objects import base
|
||||
from nova.objects import fields
|
||||
@@ -115,7 +117,7 @@ def serialize_args(fn):
|
||||
exc_tb = kwargs.get('exc_tb')
|
||||
if exc_val is not None:
|
||||
kwargs['exc_val'] = str(exc_val)
|
||||
if not isinstance(exc_tb, str) and exc_tb is not None:
|
||||
if not isinstance(exc_tb, six.string_types) and exc_tb is not None:
|
||||
kwargs['exc_tb'] = ''.join(traceback.format_tb(exc_tb))
|
||||
# NOTE(danms): We wrap a descriptor, so use that protocol
|
||||
return fn.__get__(None, cls)(*args, **kwargs)
|
||||
|
||||
@@ -267,6 +267,7 @@ class _TestInstanceActionEventObject(object):
|
||||
@mock.patch.object(traceback, 'format_tb')
|
||||
@mock.patch.object(db, 'action_event_finish')
|
||||
def test_event_finish_with_failure_legacy(self, mock_finish, mock_tb):
|
||||
# Tests that exc_tb is serialized when it's not a string type.
|
||||
mock_tb.return_value = 'fake-tb'
|
||||
timeutils.set_time_override(override_time=NOW)
|
||||
test_class = instance_action.InstanceActionEvent
|
||||
@@ -275,9 +276,28 @@ class _TestInstanceActionEventObject(object):
|
||||
expected_packed_values['finish_time'] = timeutils.utcnow()
|
||||
|
||||
mock_finish.return_value = fake_event
|
||||
fake_tb = mock.sentinel.fake_tb
|
||||
event = test_class.event_finish_with_failure(
|
||||
self.context, 'fake-uuid', 'fake-event', exc_val='val',
|
||||
exc_tb=mock.sentinel.fake_tb, want_result=True)
|
||||
exc_tb=fake_tb, want_result=True)
|
||||
mock_finish.assert_called_once_with(self.context,
|
||||
expected_packed_values)
|
||||
self.compare_obj(event, fake_event)
|
||||
mock_tb.assert_called_once_with(fake_tb)
|
||||
|
||||
@mock.patch.object(db, 'action_event_finish')
|
||||
def test_event_finish_with_failure_legacy_unicode(self, mock_finish):
|
||||
# Tests that traceback.format_tb is not called when exc_tb is unicode.
|
||||
timeutils.set_time_override(override_time=NOW)
|
||||
test_class = instance_action.InstanceActionEvent
|
||||
expected_packed_values = test_class.pack_action_event_finish(
|
||||
self.context, 'fake-uuid', 'fake-event', 'val', unicode('fake-tb'))
|
||||
expected_packed_values['finish_time'] = timeutils.utcnow()
|
||||
|
||||
mock_finish.return_value = fake_event
|
||||
event = test_class.event_finish_with_failure(
|
||||
self.context, 'fake-uuid', 'fake-event', exc_val='val',
|
||||
exc_tb=unicode('fake-tb'), want_result=True)
|
||||
mock_finish.assert_called_once_with(self.context,
|
||||
expected_packed_values)
|
||||
self.compare_obj(event, fake_event)
|
||||
@@ -285,6 +305,8 @@ class _TestInstanceActionEventObject(object):
|
||||
@mock.patch.object(traceback, 'format_tb')
|
||||
@mock.patch.object(db, 'action_event_finish')
|
||||
def test_event_finish_with_failure_no_result(self, mock_finish, mock_tb):
|
||||
# Tests that traceback.format_tb is not called when exc_tb is a str
|
||||
# and want_result is False, so no event should come back.
|
||||
mock_tb.return_value = 'fake-tb'
|
||||
timeutils.set_time_override(override_time=NOW)
|
||||
test_class = instance_action.InstanceActionEvent
|
||||
@@ -299,6 +321,7 @@ class _TestInstanceActionEventObject(object):
|
||||
mock_finish.assert_called_once_with(self.context,
|
||||
expected_packed_values)
|
||||
self.assertIsNone(event)
|
||||
self.assertFalse(mock_tb.called)
|
||||
|
||||
@mock.patch.object(db, 'action_events_get')
|
||||
def test_get_by_action(self, mock_get):
|
||||
|
||||
Reference in New Issue
Block a user