提交 72bdab0f 编写于 作者: C Cleber Rosa

avocado/utils/process.py: make CmdResult.std{out,err}_text smarter

In situations where a user of the CmdResult class manually sets the
stdout/stderr attributes to a string, instead of the recommended and
documented content of type "bytes", it won't be possible to "decode"
the bytes into a string of a given encoding, and we'll end up with
a crash.

Since the goal of std{out,err}_text is to return a text version
of stdout, if itself already is of such a type, let's just return
it.

Additionally, if the data cannot be "decode()d", let's raise an
explicit TypeError on this location, rather than later in the code
when its value is attempted to be used.
Signed-off-by: NCleber Rosa <crosa@redhat.com>
上级 a6799140
......@@ -32,6 +32,7 @@ import threading
import time
from io import BytesIO
from six import string_types
from . import gdb
from . import runtime
......@@ -294,11 +295,19 @@ class CmdResult(object):
@property
def stdout_text(self):
return self.stdout.decode(self.encoding)
if type(self.stdout) in string_types:
return self.stdout
if hasattr(self.stdout, 'decode'):
return self.stdout.decode(self.encoding)
raise TypeError("Unable to decode stdout into a string-like type")
@property
def stderr_text(self):
return self.stderr.decode(self.encoding)
if type(self.stderr) in string_types:
return self.stderr
if hasattr(self.stderr, 'decode'):
return self.stderr.decode(self.encoding)
raise TypeError("Unable to decode stderr into a string-like type")
def __repr__(self):
cmd_rep = ("Command: %s\n"
......
......@@ -12,6 +12,9 @@ from avocado.utils import gdb
from avocado.utils import process
from avocado.utils import path
from six import string_types
TRUE_CMD = path.find_command('true')
......@@ -231,6 +234,33 @@ class MiscProcessTests(unittest.TestCase):
self.assertEqual("./bin", res)
class CmdResultTests(unittest.TestCase):
def test_cmd_result_stdout_stderr_bytes(self):
result = process.CmdResult()
self.assertTrue(isinstance(result.stdout, bytes))
self.assertTrue(isinstance(result.stderr, bytes))
def test_cmd_result_stdout_stderr_text(self):
result = process.CmdResult()
self.assertTrue(isinstance(result.stdout_text, string_types))
self.assertTrue(isinstance(result.stderr_text, string_types))
def test_cmd_result_stdout_stderr_already_text(self):
result = process.CmdResult()
result.stdout = "supposed command output, but not as bytes"
result.stderr = "supposed command error, but not as bytes"
self.assertEqual(result.stdout, result.stdout_text)
self.assertEqual(result.stderr, result.stderr_text)
def test_cmd_result_stdout_stderr_other_type(self):
result = process.CmdResult()
result.stdout = None
result.stderr = None
self.assertRaises(TypeError, lambda x: result.stdout_text)
self.assertRaises(TypeError, lambda x: result.stderr_text)
class FDDrainerTests(unittest.TestCase):
def test_drain_from_pipe_fd(self):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册