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
|
||||
|
||||
|
||||
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_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:
|
||||
path = os.path.abspath(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])
|
||||
if 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:
|
||||
new_argv.extend(args)
|
||||
p = subprocess.Popen(
|
||||
@@ -329,21 +336,25 @@ def run_python(path, env=None, args=None, timeout=None):
|
||||
p.kill()
|
||||
output, _ = p.communicate(timeout=timeout)
|
||||
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
|
||||
|
||||
|
||||
def run_isolated(path, prefix='tests/isolated/', env=None, args=None, timeout=None):
|
||||
output = run_python(prefix + path, env=env, args=args, timeout=timeout).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)
|
||||
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'
|
||||
def run_isolated(path, prefix='tests/isolated/', **kwargs):
|
||||
kwargs.setdefault('expect_pass', True)
|
||||
run_python(prefix + path, **kwargs)
|
||||
|
||||
|
||||
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():
|
||||
output = run_python('', args=('-c', 'import time; time.sleep(0.5)'), timeout=0.1)
|
||||
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)
|
||||
print('pass')
|
||||
'''
|
||||
output = tests.run_python(
|
||||
tests.run_python(
|
||||
path=None,
|
||||
env={'EVENTLET_TPOOL_DNS': 'yes'},
|
||||
args=['-c', code],
|
||||
expect_pass=True,
|
||||
)
|
||||
assert output.rstrip() == b'pass'
|
||||
|
||||
|
||||
@tests.skip_with_pyevent
|
||||
|
@@ -1,15 +1,18 @@
|
||||
import os
|
||||
__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':
|
||||
try:
|
||||
import urllib.request as target
|
||||
except ImportError:
|
||||
import urllib as target
|
||||
import eventlet
|
||||
target = eventlet.import_patched('tests.patcher.shared1').shared
|
||||
t = target.socket.socket
|
||||
import eventlet.green.socket
|
||||
if issubclass(t, eventlet.green.socket.socket):
|
||||
print('pass')
|
||||
else:
|
||||
import eventlet.green.socket as g
|
||||
if not issubclass(t, g.socket):
|
||||
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():
|
||||
code = '''\
|
||||
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)
|
||||
tests.run_isolated('patcher_import_patched_defaults.py')
|
||||
|
||||
|
||||
class MonkeyPatch(ProcessBase):
|
||||
|
@@ -72,10 +72,7 @@ def test_dns_methods_are_green():
|
||||
with open(mock_sys_pkg_dir + '/dns.py', 'wb') as f:
|
||||
f.write(b'raise Exception("Your IP address string is so illegal ' +
|
||||
b'it prevents installing packages.")\n')
|
||||
tests.run_isolated(
|
||||
'socket_resolve_green.py',
|
||||
env={'PYTHONPATH': os.pathsep.join(sys.path + [mock_sys_pkg_dir])},
|
||||
)
|
||||
tests.run_isolated('socket_resolve_green.py', pythonpath_extend=[mock_sys_pkg_dir])
|
||||
finally:
|
||||
shutil.rmtree(mock_sys_pkg_dir)
|
||||
|
||||
|
6
tox.ini
6
tox.ini
@@ -42,12 +42,12 @@ basepython =
|
||||
py35: python3.5
|
||||
pypy: pypy
|
||||
deps =
|
||||
nose==1.3.1
|
||||
setuptools==5.4.1
|
||||
nose==1.3.7
|
||||
setuptools==32.3.1
|
||||
py{26,27}: subprocess32==3.2.7
|
||||
py{26,27}-{selects,poll,epolls}: MySQL-python==1.2.5
|
||||
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}: pyzmq==13.1.0
|
||||
commands =
|
||||
|
Reference in New Issue
Block a user