Merge pull request #905 from AndreMiras/feature/ticket857_test_cmd_unicode_decode

Unit test unicode decode on command output, fixes #857
This commit is contained in:
Andre Miras 2019-05-28 23:05:38 +02:00 committed by GitHub
commit 678b1bf52c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 2 deletions

View file

@ -327,7 +327,7 @@ class Buildozer(object):
ret_stdout.append(chunk)
if show_output:
if IS_PY3:
stderr.write(chunk.decode('utf-8', 'replace'))
stdout.write(chunk.decode('utf-8', 'replace'))
else:
stdout.write(chunk)
if fd_stderr in readx:

View file

@ -4,7 +4,7 @@ import codecs
import mock
import unittest
import buildozer as buildozer_module
from buildozer import Buildozer
from buildozer import Buildozer, IS_PY3
from six import StringIO
import tempfile
@ -158,3 +158,45 @@ class TestBuildozer(unittest.TestCase):
with mock.patch.object(Buildozer, 'file_exists', return_value=True):
ant_path = target._install_apache_ant()
assert ant_path == my_ant_path
def test_cmd_unicode_decode(self):
"""
Verifies Buildozer.cmd() can properly handle non-unicode outputs.
refs: https://github.com/kivy/buildozer/issues/857
"""
buildozer = Buildozer()
command = 'uname'
kwargs = {
'show_output': True,
'get_stdout': True,
'get_stderr': True,
}
command_output = b'\x80 cannot decode \x80'
# showing the point that we can't decode it
with self.assertRaises(UnicodeDecodeError):
command_output.decode('utf-8')
with mock.patch('buildozer.Popen') as m_popen, \
mock.patch('buildozer.select') as m_select, \
mock.patch('buildozer.stdout') as m_stdout:
m_select.select().__getitem__.return_value = [0]
# makes sure fcntl.fcntl() gets what it expects so it doesn't crash
m_popen().stdout.fileno.return_value = 0
m_popen().stderr.fileno.return_value = 2
# Buildozer.cmd() is iterating through command output "chunk" until
# one chunk is None
m_popen().stdout.read.side_effect = [command_output, None]
m_popen().returncode = 0
stdout, stderr, returncode = buildozer.cmd(command, **kwargs)
# when get_stdout is True, the command output also gets returned
assert stdout == command_output.decode('utf-8', 'ignore')
assert stderr is None
assert returncode == 0
# Python2 and Python3 have different approaches for decoding the output
if IS_PY3:
assert m_stdout.write.call_args_list == [
mock.call(command_output.decode('utf-8', 'replace'))
]
else:
assert m_stdout.write.call_args_list == [
mock.call(command_output)
]