Merge "Truncate encoded instance message to 255 or fewer"

This commit is contained in:
Jenkins 2014-11-21 18:12:24 +00:00 committed by Gerrit Code Review
commit 3ada19a650
2 changed files with 37 additions and 1 deletions

View File

@ -19,6 +19,7 @@ import string
import traceback
from oslo.config import cfg
from oslo.utils import encodeutils
from nova import block_device
from nova.compute import flavors
@ -64,7 +65,19 @@ def exception_to_dict(fault):
# NOTE(dripton) The message field in the database is limited to 255 chars.
# MySQL silently truncates overly long messages, but PostgreSQL throws an
# error if we don't truncate it.
u_message = unicode(message)[:255]
b_message = encodeutils.safe_encode(message)[:255]
# NOTE(chaochin) UTF-8 character byte size varies from 1 to 6. If
# truncating a long byte string to 255, the last character may be
# cut in the middle, so that UnicodeDecodeError will occur when
# converting it back to unicode.
decode_ok = False
while not decode_ok:
try:
u_message = encodeutils.safe_decode(b_message)
decode_ok = True
except UnicodeDecodeError:
b_message = b_message[:-1]
fault_dict = dict(exception=fault)
fault_dict["message"] = u_message

View File

@ -22,6 +22,7 @@ import string
import mock
from oslo.config import cfg
from oslo.serialization import jsonutils
from oslo.utils import encodeutils
from oslo.utils import importutils
import six
import testtools
@ -825,3 +826,25 @@ class ComputeUtilsGetRebootTypes(test.NoDBTestCase):
def test_get_reboot_not_running_hard(self):
reboot_type = compute_utils.get_reboot_type('foo', 'bar')
self.assertEqual(reboot_type, 'HARD')
class ComputeUtilsTestCase(test.NoDBTestCase):
def test_exception_to_dict_with_long_message_3_bytes(self):
# Generate Chinese byte string whose length is 300. This Chinese UTF-8
# character occupies 3 bytes. After truncating, the byte string length
# should be 255.
msg = encodeutils.safe_decode('\xe8\xb5\xb5' * 100)
exc = exception.NovaException(message=msg)
fault_dict = compute_utils.exception_to_dict(exc)
byte_message = encodeutils.safe_encode(fault_dict["message"])
self.assertEqual(255, len(byte_message))
def test_exception_to_dict_with_long_message_2_bytes(self):
# Generate Russian byte string whose length is 300. This Russian UTF-8
# character occupies 2 bytes. After truncating, the byte string length
# should be 254.
msg = encodeutils.safe_decode('\xd0\x92' * 150)
exc = exception.NovaException(message=msg)
fault_dict = compute_utils.exception_to_dict(exc)
byte_message = encodeutils.safe_encode(fault_dict["message"])
self.assertEqual(254, len(byte_message))