Skip to content

Commit

Permalink
Unit test unicode decode on command output, fixes #857
Browse files Browse the repository at this point in the history
Also fixes stderr/stdout writing refs #743.
  • Loading branch information
AndreMiras committed May 28, 2019
1 parent f729829 commit 11b733c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
2 changes: 1 addition & 1 deletion buildozer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ def cmd(self, command, **kwargs):
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:
Expand Down
44 changes: 43 additions & 1 deletion tests/test_buildozer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
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

Expand Down Expand Up @@ -158,3 +158,45 @@ def test_android_ant_path(self):
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)
]

0 comments on commit 11b733c

Please sign in to comment.