Python 3: encode or decode i/o data of Popen.communicate()

In Python 3, input and output for Popen.communicate() is bytes type.
Therefore, encode input data and decode return data for Popen.communicate().

Change-Id: Id6d85eea4c771ac9756ef08ba80ebc09005fcc3e
Related Change-Id: I70f009e3366f0eeda5790652ea14f3627b934664
This commit is contained in:
fumihiko kakuma 2015-10-02 21:25:53 +09:00
parent 31cfdbd407
commit a1725700ab
2 changed files with 38 additions and 8 deletions

View File

@ -21,6 +21,7 @@ from multiprocessing import managers
import os
import shutil
import signal
import six
import stat
import sys
import tempfile
@ -52,7 +53,12 @@ class RootwrapClass(object):
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if six.PY3 and stdin is not None:
stdin = os.fsencode(stdin)
out, err = obj.communicate(stdin)
if six.PY3:
out = os.fsdecode(out)
err = os.fsdecode(err)
return obj.returncode, out, err
def shutdown(self):

View File

@ -59,17 +59,29 @@ sh: CommandFilter, /bin/sh, root
id: CommandFilter, /usr/bin/id, nobody
""")
def test_run_once(self):
def _test_run_once(self, expect_byte=True):
code, out, err = self.execute(['echo', 'teststr'])
self.assertEqual(0, code)
self.assertEqual(b'teststr\n', out)
self.assertEqual(b'', err)
if expect_byte:
expect_out = b'teststr\n'
expect_err = b''
else:
expect_out = 'teststr\n'
expect_err = ''
self.assertEqual(expect_out, out)
self.assertEqual(expect_err, err)
def test_run_with_stdin(self):
def _test_run_with_stdin(self, expect_byte=True):
code, out, err = self.execute(['cat'], stdin=b'teststr')
self.assertEqual(0, code)
self.assertEqual(b'teststr', out)
self.assertEqual(b'', err)
if expect_byte:
expect_out = b'teststr'
expect_err = b''
else:
expect_out = 'teststr'
expect_err = ''
self.assertEqual(expect_out, out)
self.assertEqual(expect_err, err)
def test_run_as(self):
if os.getuid() != 0:
@ -106,6 +118,12 @@ class RootwrapTest(_FunctionalBase, testtools.TestCase):
content.text_content(err.decode('utf-8', 'replace')))
return proc.returncode, out, err
def test_run_once(self):
self._test_run_once(expect_byte=True)
def test_run_with_stdin(self):
self._test_run_with_stdin(expect_byte=True)
class RootwrapDaemonTest(_FunctionalBase, testtools.TestCase):
def assert_unpatched(self):
@ -159,6 +177,12 @@ class RootwrapDaemonTest(_FunctionalBase, testtools.TestCase):
self.execute = self.client.execute
def test_run_once(self):
self._test_run_once(expect_byte=False)
def test_run_with_stdin(self):
self._test_run_with_stdin(expect_byte=False)
def test_error_propagation(self):
self.assertRaises(wrapper.NoFilterMatched, self.execute, ['other'])
@ -200,8 +224,8 @@ class RootwrapDaemonTest(_FunctionalBase, testtools.TestCase):
raise self._thread_res # Python 3 will even provide nice traceback
code, out, err = self._thread_res
self.assertEqual(0, code)
self.assertEqual(b'OK\n', out)
self.assertEqual(b'', err)
self.assertEqual('OK\n', out)
self.assertEqual('', err)
@contextlib.contextmanager
def _test_daemon_cleanup(self):