diff --git a/oslo_rootwrap/daemon.py b/oslo_rootwrap/daemon.py index 20de185..5409dfd 100644 --- a/oslo_rootwrap/daemon.py +++ b/oslo_rootwrap/daemon.py @@ -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): diff --git a/oslo_rootwrap/tests/test_functional.py b/oslo_rootwrap/tests/test_functional.py index 7013d85..2201d82 100644 --- a/oslo_rootwrap/tests/test_functional.py +++ b/oslo_rootwrap/tests/test_functional.py @@ -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):