未验证 提交 507e50d1 编写于 作者: L Lukáš Doktor

Merging pull request 2623

Signed-off-by: NLukáš Doktor <ldoktor@redhat.com>

* https://github.com/avocado-framework/avocado:
  utils.partition: Use encoding instead of bytes
  test: Allow unicode in exception (and tests results in general)
  utils.astring: Allow converting any object "to_text"
  utils.astring: Use prefered encoding as default to `to_text` method
  utils.astring: Add preferred ENCODING
......@@ -997,20 +997,20 @@ class Test(unittest.TestCase, TestData):
except exceptions.TestBaseException as detail:
self.__status = detail.status
self.__fail_class = detail.__class__.__name__
self.__fail_reason = str(detail)
self.__fail_reason = astring.to_text(detail)
self.__traceback = stacktrace.prepare_exc_info(sys.exc_info())
except AssertionError as detail:
self.__status = 'FAIL'
self.__fail_class = detail.__class__.__name__
self.__fail_reason = str(detail)
self.__fail_reason = astring.to_text(detail)
self.__traceback = stacktrace.prepare_exc_info(sys.exc_info())
except Exception as detail:
self.__status = 'ERROR'
tb_info = stacktrace.tb_info(sys.exc_info())
self.__traceback = stacktrace.prepare_exc_info(sys.exc_info())
try:
self.__fail_class = str(detail.__class__.__name__)
self.__fail_reason = str(detail)
self.__fail_class = astring.to_text(detail.__class__.__name__)
self.__fail_reason = astring.to_text(detail)
except TypeError:
self.__fail_class = "Exception"
self.__fail_reason = ("Unable to get exception, check the "
......
......@@ -23,6 +23,7 @@ import os
from avocado.core.output import LOG_UI
from avocado.core.parser import FileOrStdoutAction
from avocado.core.plugin_interfaces import CLI, Result
from avocado.utils import astring
UNKNOWN = '<unknown>'
......@@ -44,7 +45,7 @@ class JSONResult(Result):
'whiteboard': test.get('whiteboard', UNKNOWN),
'logdir': test.get('logdir', UNKNOWN),
'logfile': test.get('logfile', UNKNOWN),
'fail_reason': str(test.get('fail_reason', UNKNOWN))})
'fail_reason': astring.to_text(test.get('fail_reason', UNKNOWN))})
content = {'job_id': result.job_unique_id,
'debuglog': result.logfile,
'tests': tests,
......
......@@ -23,7 +23,7 @@ from xml.dom.minidom import Document
from avocado.core.parser import FileOrStdoutAction
from avocado.core.output import LOG_UI
from avocado.core.plugin_interfaces import CLI, Result
from avocado.utils import data_structures
from avocado.utils import astring, data_structures
class XUnitResult(Result):
......@@ -36,7 +36,7 @@ class XUnitResult(Result):
def _escape_attr(self, attrib):
attrib = ''.join(_ if _ in self.PRINTABLE else "\\x%02x" % ord(_)
for _ in str(attrib))
for _ in astring.to_text(attrib, encoding='utf-8'))
return attrib
def _escape_cdata(self, cdata):
......
......@@ -26,6 +26,7 @@ And not notice until their code starts failing.
"""
import itertools
import locale
import re
import sys
import string
......@@ -35,6 +36,12 @@ from six.moves import zip
from six.moves import xrange as range
#: On import evaluated value representing the system encoding
#: based on system locales using :func:`locale.getpreferredencoding`.
#: Use this value wisely as some files are dumped in different
#: encoding.
ENCODING = locale.getpreferredencoding()
#: String containing all fs-unfriendly chars (Windows-fat/Linux-ext3)
FS_UNSAFE_CHARS = '<>:"/\\|?*;'
......@@ -313,21 +320,27 @@ def is_text(data):
return isinstance(data, str)
def to_text(data, encoding=None):
def to_text(data, encoding=ENCODING):
"""
Convert data to text
Convert anything to text decoded text
Action is only taken if data is "bytes", in which case it's
decoded into the given encoding and should produce a type that
passes the is_text() check.
When the data is bytes, it's decoded. When it's not of string types
it's re-formatted into text and returned. Otherwise (it's string)
it's returned unchanged.
:param data: data to be transformed into text
:param encoding: encoding of the data (only used when decoding
is necessary)
:type data: either bytes or other data that will be returned
unchanged
"""
if is_bytes(data):
if encoding is None:
return data.decode()
encoding = ENCODING
return data.decode(encoding)
elif not isinstance(data, string_types):
if sys.version_info[0] < 3:
return unicode(data) # pylint: disable=E0602
else:
return data.decode(encoding)
return str(data)
return data
......@@ -109,9 +109,9 @@ class Partition(object):
"""
# list mounted file systems
devices = [line.split()[0]
for line in process.system_output('mount').splitlines()]
for line in process.getoutput('mount').splitlines()]
# list mounted swap devices
swaps = process.system_output('swapon -s').splitlines()
swaps = process.getoutput('swapon -s').splitlines()
devices.extend([line.split()[0] for line in swaps
if line.startswith('/')])
return devices
......@@ -122,7 +122,7 @@ class Partition(object):
Lists the mount points.
"""
return [line.split()[2]
for line in process.system_output('mount').splitlines()]
for line in process.getoutput('mount').splitlines()]
def get_mountpoint(self, filename=None):
"""
......@@ -254,7 +254,7 @@ class Partition(object):
# Try to kill all pids
for pid in (line.split()[1] for line in out.splitlines()[1:]):
try:
process.system("kill -9 %s" % pid, ignore_status=True,
process.system("kill -9 %d" % int(pid), ignore_status=True,
sudo=True)
except OSError:
pass
......
......@@ -27,7 +27,7 @@ class FailTest(Test):
"""
Avocado should report this as TestError.
"""
raise NastyException("Nasty-string-like-exception")
raise NastyException(u"Nasty-string-like-exception\u017e")
if __name__ == "__main__":
......
......@@ -14,6 +14,9 @@ class NastyException(Exception):
def __str__(self):
return self.msg
def __unicode__(self):
return self.msg
class FailTest(Test):
......
......@@ -29,6 +29,7 @@ import pystache
from avocado.core import exit_codes
from avocado.core.output import LOG_UI
from avocado.core.plugin_interfaces import CLI, Result
from avocado.utils import astring
class ReportModel(object):
......@@ -156,7 +157,7 @@ class ReportModel(object):
fail_reason = tst.get('fail_reason')
if fail_reason is None:
fail_reason = '<unknown>'
fail_reason = str(fail_reason)
fail_reason = astring.to_text(fail_reason)
if len(fail_reason) > exhibition_limit:
fail_reason = ('<a data-container="body" '
'data-toggle="popover" '
......
......@@ -3,7 +3,7 @@ import sys
import unittest
from avocado.core import exit_codes
from avocado.utils import process
from avocado.utils import process, astring
basedir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..')
......@@ -24,7 +24,8 @@ class StandaloneTests(unittest.TestCase):
def run_and_check(self, cmd_line, expected_rc, tstname):
os.chdir(basedir)
result = process.run(cmd_line, ignore_status=True)
result = process.run(cmd_line, ignore_status=True,
encoding=astring.ENCODING)
self.assertEqual(result.exit_status, expected_rc,
"Stand alone %s did not return rc "
"%d:\n%s" % (tstname, expected_rc, result))
......@@ -50,10 +51,10 @@ class StandaloneTests(unittest.TestCase):
expected_rc = exit_codes.AVOCADO_TESTS_FAIL
result = self.run_and_check(cmd_line, expected_rc, 'errortest_nasty')
if sys.version_info[0] == 3:
exc = "errortest_nasty.NastyException: Nasty-string-like-exception"
exc = u"errortest_nasty.NastyException: Nasty-string-like-exception\u017e"
else:
exc = "NastyException: Nasty-string-like-exception"
count = result.stdout_text.count("\n%s" % exc)
exc = u"NastyException: Nasty-string-like-exception\\u017e"
count = result.stdout_text.count(u"\n%s" % exc)
self.assertEqual(count, 2, "Exception \\n%s should be present twice in"
"the log (once from the log, second time when parsing"
"exception details." % (exc))
......
......@@ -116,12 +116,16 @@ class AstringTest(unittest.TestCase):
self.assertTrue(astring.is_text(astring.to_text('', 'ascii')))
self.assertTrue(astring.is_text(astring.to_text(u'', 'ascii')))
def test_to_text_decode_utf_8(self):
def test_to_text(self):
text_1 = astring.to_text(b'\xc3\xa1', 'utf-8')
text_2 = astring.to_text(u'\u00e1', 'utf-8')
self.assertTrue(astring.is_text(text_1))
self.assertTrue(astring.is_text(text_1))
self.assertEqual(text_1, text_2)
self.assertEqual(astring.to_text(Exception(u'\u00e1')),
u"\xe1")
# For tuple, dict and others astring.to_text is equivalent of str()
# because on py3 it's unicode and on py2 it uses __repr__ (is encoded)
self.assertEqual(astring.to_text({u'\xe1': 1}), str({u'\xe1': 1}))
if __name__ == '__main__':
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册