From d13fbc5bfbd75f26e1a45e1944b05eefc2fe3b7b Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 5 Oct 2020 11:25:43 -0700 Subject: [PATCH 1/2] Remove uses of PIPE --- .../tests/fork/_fork_interop_test.py | 34 +++++++++---------- src/python/grpcio_tests/tests/fork/methods.py | 3 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py index e2eff257fa1..731dcb12442 100644 --- a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py +++ b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py @@ -16,6 +16,7 @@ import six import subprocess import sys +import tempfile import threading import unittest from grpc._cython import cygrpc @@ -69,10 +70,11 @@ class ForkInteropTest(unittest.TestCase): while True: time.sleep(1) """ + streams = tuple(tempfile.TemporaryFile() for _ in range(2)) self._server_process = subprocess.Popen( [sys.executable, '-c', start_server_script], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stdout=streams[0], + stderr=streams[1]) timer = threading.Timer(_SUBPROCESS_TIMEOUT_S, self._server_process.kill) try: @@ -125,26 +127,22 @@ class ForkInteropTest(unittest.TestCase): def _verifyTestCase(self, test_case): script = _CLIENT_FORK_SCRIPT_TEMPLATE % (test_case.name, self._port) + streams = tuple(tempfile.TemporaryFile() for _ in range(2)) process = subprocess.Popen([sys.executable, '-c', script], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stdout=streams[0], + stderr=streams[1]) timer = threading.Timer(_SUBPROCESS_TIMEOUT_S, process.kill) - try: - timer.start() - try: - out, err = process.communicate(timeout=_SUBPROCESS_TIMEOUT_S) - except TypeError: - # The timeout parameter was added in Python 3.3. - out, err = process.communicate() - except subprocess.TimeoutExpired: - process.kill() - raise RuntimeError('Process failed to terminate') - finally: - timer.cancel() + timer.start() + process.wait() + timer.cancel() + outputs = [] + for stream in streams: + stream.seek(0) + outputs.append(stream.read()) self.assertEqual( 0, process.returncode, - 'process failed with exit code %d (stdout: %s, stderr: %s)' % - (process.returncode, out, err)) + 'process failed with exit code %d (stdout: "%s", stderr: "%s")' % + (process.returncode, outputs[0], outputs[1])) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/fork/methods.py b/src/python/grpcio_tests/tests/fork/methods.py index 2123c699161..3ccebcf6510 100644 --- a/src/python/grpcio_tests/tests/fork/methods.py +++ b/src/python/grpcio_tests/tests/fork/methods.py @@ -142,7 +142,8 @@ class _ChildProcess(object): self._process.exitcode) try: exception = self._exceptions.get(block=False) - raise ValueError('Child process failed: %s' % exception) + raise ValueError('Child process failed: "%s": "%s"' % + (repr(exception), exception)) except queue.Empty: pass From 3dc0b3b6250b75f5b579931ba67738438837671d Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 5 Oct 2020 15:29:45 -0700 Subject: [PATCH 2/2] Get port properly --- src/python/grpcio_tests/tests/fork/_fork_interop_test.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py index 731dcb12442..7ff4751a090 100644 --- a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py +++ b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py @@ -79,7 +79,14 @@ class ForkInteropTest(unittest.TestCase): self._server_process.kill) try: timer.start() - self._port = int(self._server_process.stdout.readline()) + while True: + streams[0].seek(0) + s = streams[0].readline() + if not s: + continue + else: + self._port = int(s) + break except ValueError: raise Exception('Failed to get port from server') finally: