From 001f31f8f8dfc581795f282609027b26c8a31833 Mon Sep 17 00:00:00 2001 From: Sergey Shepelev Date: Sun, 6 Sep 2015 03:43:42 +0300 Subject: [PATCH] greenio: socket.recv() could return str; Thanks to jerzyk It must always return bytes. https://github.com/eventlet/eventlet/issues/245 --- eventlet/greenio/base.py | 2 +- tests/__init__.py | 13 +++++++++---- tests/socket_test.py | 23 +++++++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/eventlet/greenio/base.py b/eventlet/greenio/base.py index 1e43176..18799af 100644 --- a/eventlet/greenio/base.py +++ b/eventlet/greenio/base.py @@ -315,7 +315,7 @@ class GreenSocket(object): if get_errno(e) in SOCKET_BLOCKING: pass elif get_errno(e) in SOCKET_CLOSED: - return '' + return b'' else: raise try: diff --git a/tests/__init__.py b/tests/__init__.py index 26c0c2e..e20561b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -292,13 +292,15 @@ def get_database_auth(): return retval -def run_python(path): +def run_python(path, env=None): if not path.endswith('.py'): path += '.py' path = os.path.abspath(path) src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) new_env = os.environ.copy() new_env['PYTHONPATH'] = os.pathsep.join(sys.path + [src_dir]) + if env: + new_env.update(env) p = subprocess.Popen( [sys.executable, path], env=new_env, @@ -310,15 +312,18 @@ def run_python(path): return output -def run_isolated(path, prefix='tests/isolated/'): - output = run_python(prefix + path).rstrip() +def run_isolated(path, prefix='tests/isolated/', env=None): + output = run_python(prefix + path, env=env).rstrip() if output.startswith(b'skip'): parts = output.split(b':', 1) skip_args = [] if len(parts) > 1: skip_args.append(parts[1]) raise SkipTest(*skip_args) - assert output == b'pass', output + ok = output == b'pass' + if not ok: + sys.stderr.write('Isolated test {0} output:\n---\n{1}\n---\n'.format(path, output.decode())) + assert ok, 'Expected single line "pass" in stdout' certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt') diff --git a/tests/socket_test.py b/tests/socket_test.py index 60881f7..634e1f0 100644 --- a/tests/socket_test.py +++ b/tests/socket_test.py @@ -1,3 +1,4 @@ +import eventlet from eventlet.green import socket @@ -6,3 +7,25 @@ def test_create_connection_error(): socket.create_connection(('192.0.2.1', 80), timeout=0.1) except (IOError, OSError): pass + + +def test_recv_type(): + # https://github.com/eventlet/eventlet/issues/245 + # socket recv returning multiple data types + # For this test to work, client and server have to be in separate + # processes or OS threads. Just running two greenthreads gives + # false test pass. + threading = eventlet.patcher.original('threading') + addr = [] + + def server(): + sock = eventlet.listen(('127.0.0.1', 0)) + addr[:] = sock.getsockname() + eventlet.sleep(0.2) + + server_thread = threading.Thread(target=server) + server_thread.start() + eventlet.sleep(0.1) + sock = eventlet.connect(tuple(addr)) + s = sock.recv(1) + assert isinstance(s, bytes)