greenio: socket.recv() could return str; Thanks to jerzyk

It must always return bytes.
https://github.com/eventlet/eventlet/issues/245
This commit is contained in:
Sergey Shepelev
2015-09-06 03:43:42 +03:00
parent c3ce3eef0b
commit 001f31f8f8
3 changed files with 33 additions and 5 deletions

View File

@@ -315,7 +315,7 @@ class GreenSocket(object):
if get_errno(e) in SOCKET_BLOCKING: if get_errno(e) in SOCKET_BLOCKING:
pass pass
elif get_errno(e) in SOCKET_CLOSED: elif get_errno(e) in SOCKET_CLOSED:
return '' return b''
else: else:
raise raise
try: try:

View File

@@ -292,13 +292,15 @@ def get_database_auth():
return retval return retval
def run_python(path): def run_python(path, env=None):
if not path.endswith('.py'): if not path.endswith('.py'):
path += '.py' path += '.py'
path = os.path.abspath(path) path = os.path.abspath(path)
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
new_env = os.environ.copy() new_env = os.environ.copy()
new_env['PYTHONPATH'] = os.pathsep.join(sys.path + [src_dir]) new_env['PYTHONPATH'] = os.pathsep.join(sys.path + [src_dir])
if env:
new_env.update(env)
p = subprocess.Popen( p = subprocess.Popen(
[sys.executable, path], [sys.executable, path],
env=new_env, env=new_env,
@@ -310,15 +312,18 @@ def run_python(path):
return output return output
def run_isolated(path, prefix='tests/isolated/'): def run_isolated(path, prefix='tests/isolated/', env=None):
output = run_python(prefix + path).rstrip() output = run_python(prefix + path, env=env).rstrip()
if output.startswith(b'skip'): if output.startswith(b'skip'):
parts = output.split(b':', 1) parts = output.split(b':', 1)
skip_args = [] skip_args = []
if len(parts) > 1: if len(parts) > 1:
skip_args.append(parts[1]) skip_args.append(parts[1])
raise SkipTest(*skip_args) 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') certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')

View File

@@ -1,3 +1,4 @@
import eventlet
from eventlet.green import socket 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) socket.create_connection(('192.0.2.1', 80), timeout=0.1)
except (IOError, OSError): except (IOError, OSError):
pass 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)