test_import_patched_defaults bended to play with pyopenssl>=16.1.0
Basically this patch replaces urllib with custom module that is guaranteed not imported before patching. https://github.com/eventlet/eventlet/issues/362 More general issue here https://github.com/eventlet/eventlet/issues/368
This commit is contained in:
@@ -302,16 +302,23 @@ def get_database_auth():
|
|||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
|
||||||
def run_python(path, env=None, args=None, timeout=None):
|
def run_python(path, env=None, args=None, timeout=None, pythonpath_extend=None, expect_pass=False):
|
||||||
new_argv = [sys.executable]
|
new_argv = [sys.executable]
|
||||||
new_env = os.environ.copy()
|
new_env = os.environ.copy()
|
||||||
|
new_env.setdefault('eventlet_test_in_progress', 'yes')
|
||||||
|
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
if path:
|
if path:
|
||||||
path = os.path.abspath(path)
|
path = os.path.abspath(path)
|
||||||
new_argv.append(path)
|
new_argv.append(path)
|
||||||
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
new_env['PYTHONPATH'] = os.pathsep.join(sys.path + [src_dir])
|
new_env['PYTHONPATH'] = os.pathsep.join(sys.path + [src_dir])
|
||||||
if env:
|
if env:
|
||||||
new_env.update(env)
|
new_env.update(env)
|
||||||
|
if pythonpath_extend:
|
||||||
|
new_path = [p for p in new_env.get('PYTHONPATH', '').split(os.pathsep) if p]
|
||||||
|
new_path.extend(
|
||||||
|
p if os.path.isabs(p) else os.path.join(src_dir, p) for p in pythonpath_extend
|
||||||
|
)
|
||||||
|
new_env['PYTHONPATH'] = os.pathsep.join(new_path)
|
||||||
if args:
|
if args:
|
||||||
new_argv.extend(args)
|
new_argv.extend(args)
|
||||||
p = subprocess.Popen(
|
p = subprocess.Popen(
|
||||||
@@ -329,21 +336,25 @@ def run_python(path, env=None, args=None, timeout=None):
|
|||||||
p.kill()
|
p.kill()
|
||||||
output, _ = p.communicate(timeout=timeout)
|
output, _ = p.communicate(timeout=timeout)
|
||||||
return '{0}\nFAIL - timed out'.format(output).encode()
|
return '{0}\nFAIL - timed out'.format(output).encode()
|
||||||
|
|
||||||
|
if expect_pass:
|
||||||
|
if output.startswith(b'skip'):
|
||||||
|
parts = output.rstrip().split(b':', 1)
|
||||||
|
skip_args = []
|
||||||
|
if len(parts) > 1:
|
||||||
|
skip_args.append(parts[1])
|
||||||
|
raise SkipTest(*skip_args)
|
||||||
|
ok = output.rstrip() == b'pass'
|
||||||
|
if not ok:
|
||||||
|
sys.stderr.write('Program {0} output:\n---\n{1}\n---\n'.format(path, output.decode()))
|
||||||
|
assert ok, 'Expected single line "pass" in stdout'
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def run_isolated(path, prefix='tests/isolated/', env=None, args=None, timeout=None):
|
def run_isolated(path, prefix='tests/isolated/', **kwargs):
|
||||||
output = run_python(prefix + path, env=env, args=args, timeout=timeout).rstrip()
|
kwargs.setdefault('expect_pass', True)
|
||||||
if output.startswith(b'skip'):
|
run_python(prefix + path, **kwargs)
|
||||||
parts = output.split(b':', 1)
|
|
||||||
skip_args = []
|
|
||||||
if len(parts) > 1:
|
|
||||||
skip_args.append(parts[1])
|
|
||||||
raise SkipTest(*skip_args)
|
|
||||||
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')
|
||||||
@@ -353,3 +364,10 @@ private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
|||||||
def test_run_python_timeout():
|
def test_run_python_timeout():
|
||||||
output = run_python('', args=('-c', 'import time; time.sleep(0.5)'), timeout=0.1)
|
output = run_python('', args=('-c', 'import time; time.sleep(0.5)'), timeout=0.1)
|
||||||
assert output.endswith(b'FAIL - timed out')
|
assert output.endswith(b'FAIL - timed out')
|
||||||
|
|
||||||
|
|
||||||
|
def test_run_python_pythonpath_extend():
|
||||||
|
code = '''import os, sys ; print('\\n'.join(sys.path))'''
|
||||||
|
output = run_python('', args=('-c', code), pythonpath_extend=('dira', 'dirb'))
|
||||||
|
assert b'/dira\n' in output
|
||||||
|
assert b'/dirb\n' in output
|
||||||
|
@@ -19,12 +19,12 @@ socket.gethostbyname('localhost')
|
|||||||
socket.getaddrinfo('localhost', 80)
|
socket.getaddrinfo('localhost', 80)
|
||||||
print('pass')
|
print('pass')
|
||||||
'''
|
'''
|
||||||
output = tests.run_python(
|
tests.run_python(
|
||||||
path=None,
|
path=None,
|
||||||
env={'EVENTLET_TPOOL_DNS': 'yes'},
|
env={'EVENTLET_TPOOL_DNS': 'yes'},
|
||||||
args=['-c', code],
|
args=['-c', code],
|
||||||
|
expect_pass=True,
|
||||||
)
|
)
|
||||||
assert output.rstrip() == b'pass'
|
|
||||||
|
|
||||||
|
|
||||||
@tests.skip_with_pyevent
|
@tests.skip_with_pyevent
|
||||||
|
@@ -1,15 +1,18 @@
|
|||||||
import os
|
|
||||||
__test__ = False
|
__test__ = False
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
# On eventlet<=0.20.0 uncommenting this unpatched import fails test
|
||||||
|
# because import_patched did not agressively repatch sub-imported modules cached in sys.modules
|
||||||
|
# to be fixed in https://github.com/eventlet/eventlet/issues/368
|
||||||
|
# import tests.patcher.shared_import_socket
|
||||||
|
|
||||||
if os.environ.get('eventlet_test_import_patched_defaults') == '1':
|
import eventlet
|
||||||
try:
|
target = eventlet.import_patched('tests.patcher.shared1').shared
|
||||||
import urllib.request as target
|
|
||||||
except ImportError:
|
|
||||||
import urllib as target
|
|
||||||
t = target.socket.socket
|
t = target.socket.socket
|
||||||
import eventlet.green.socket
|
import eventlet.green.socket as g
|
||||||
if issubclass(t, eventlet.green.socket.socket):
|
if not issubclass(t, g.socket):
|
||||||
print('pass')
|
|
||||||
else:
|
|
||||||
print('Fail. Target socket not green: {0} bases {1}'.format(t, t.__bases__))
|
print('Fail. Target socket not green: {0} bases {1}'.format(t, t.__bases__))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print('pass')
|
||||||
|
0
tests/patcher/__init__.py
Normal file
0
tests/patcher/__init__.py
Normal file
11
tests/patcher/shared1.py
Normal file
11
tests/patcher/shared1.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import os
|
||||||
|
__test__ = False
|
||||||
|
shared = None
|
||||||
|
|
||||||
|
|
||||||
|
if os.environ.get('eventlet_test_in_progress') == 'yes':
|
||||||
|
# pyopenssl imported urllib before we could patch it
|
||||||
|
# we can ensure this shared module was not imported
|
||||||
|
# https://github.com/eventlet/eventlet/issues/362
|
||||||
|
import tests.patcher.shared_import_socket as shared
|
||||||
|
_ = shared # mask unused import error
|
7
tests/patcher/shared_import_socket.py
Normal file
7
tests/patcher/shared_import_socket.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import os
|
||||||
|
import socket
|
||||||
|
__test__ = False
|
||||||
|
_ = socket # mask unused import error
|
||||||
|
|
||||||
|
# prevent accidental imports
|
||||||
|
assert os.environ.get('eventlet_test_in_progress') == 'yes'
|
@@ -84,17 +84,7 @@ class ImportPatched(ProcessBase):
|
|||||||
|
|
||||||
|
|
||||||
def test_import_patched_defaults():
|
def test_import_patched_defaults():
|
||||||
code = '''\
|
tests.run_isolated('patcher_import_patched_defaults.py')
|
||||||
import eventlet
|
|
||||||
eventlet.import_patched('patcher_import_patched_defaults')
|
|
||||||
'''
|
|
||||||
isolated_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/tests/isolated'
|
|
||||||
env = {
|
|
||||||
'eventlet_test_import_patched_defaults': '1',
|
|
||||||
'PYTHONPATH': os.pathsep.join(sys.path + [isolated_path]),
|
|
||||||
}
|
|
||||||
output = tests.run_python(path=None, env=env, args=['-c', code])
|
|
||||||
assert output.rstrip() == b'pass', repr(output)
|
|
||||||
|
|
||||||
|
|
||||||
class MonkeyPatch(ProcessBase):
|
class MonkeyPatch(ProcessBase):
|
||||||
|
@@ -72,10 +72,7 @@ def test_dns_methods_are_green():
|
|||||||
with open(mock_sys_pkg_dir + '/dns.py', 'wb') as f:
|
with open(mock_sys_pkg_dir + '/dns.py', 'wb') as f:
|
||||||
f.write(b'raise Exception("Your IP address string is so illegal ' +
|
f.write(b'raise Exception("Your IP address string is so illegal ' +
|
||||||
b'it prevents installing packages.")\n')
|
b'it prevents installing packages.")\n')
|
||||||
tests.run_isolated(
|
tests.run_isolated('socket_resolve_green.py', pythonpath_extend=[mock_sys_pkg_dir])
|
||||||
'socket_resolve_green.py',
|
|
||||||
env={'PYTHONPATH': os.pathsep.join(sys.path + [mock_sys_pkg_dir])},
|
|
||||||
)
|
|
||||||
finally:
|
finally:
|
||||||
shutil.rmtree(mock_sys_pkg_dir)
|
shutil.rmtree(mock_sys_pkg_dir)
|
||||||
|
|
||||||
|
6
tox.ini
6
tox.ini
@@ -42,12 +42,12 @@ basepython =
|
|||||||
py35: python3.5
|
py35: python3.5
|
||||||
pypy: pypy
|
pypy: pypy
|
||||||
deps =
|
deps =
|
||||||
nose==1.3.1
|
nose==1.3.7
|
||||||
setuptools==5.4.1
|
setuptools==32.3.1
|
||||||
py{26,27}: subprocess32==3.2.7
|
py{26,27}: subprocess32==3.2.7
|
||||||
py{26,27}-{selects,poll,epolls}: MySQL-python==1.2.5
|
py{26,27}-{selects,poll,epolls}: MySQL-python==1.2.5
|
||||||
py26-{selects,poll,epolls}: pyopenssl==0.13
|
py26-{selects,poll,epolls}: pyopenssl==0.13
|
||||||
py{27,33,34}-{selects,poll,epolls}: pyopenssl==16.0.0
|
py{27,33,34}-{selects,poll,epolls}: pyopenssl==16.2.0
|
||||||
{selects,poll,epolls}: psycopg2cffi-compat==1.1
|
{selects,poll,epolls}: psycopg2cffi-compat==1.1
|
||||||
{selects,poll,epolls}: pyzmq==13.1.0
|
{selects,poll,epolls}: pyzmq==13.1.0
|
||||||
commands =
|
commands =
|
||||||
|
Reference in New Issue
Block a user