Added monkeypatch stdlib tests, which test how well monkeypatching works. Unsurprisingly, some tweakage was also needed.
This commit is contained in:
@@ -11,19 +11,21 @@ __patched__ = ['fdopen', 'read', 'write', 'wait', 'waitpid']
|
|||||||
for var in dir(os_orig):
|
for var in dir(os_orig):
|
||||||
exec "%s = os_orig.%s" % (var, var)
|
exec "%s = os_orig.%s" % (var, var)
|
||||||
|
|
||||||
|
__original_fdopen__ = os_orig.fdopen
|
||||||
def fdopen(*args, **kw):
|
def fdopen(*args, **kw):
|
||||||
"""fdopen(fd [, mode='r' [, bufsize]]) -> file_object
|
"""fdopen(fd [, mode='r' [, bufsize]]) -> file_object
|
||||||
|
|
||||||
Return an open file object connected to a file descriptor."""
|
Return an open file object connected to a file descriptor."""
|
||||||
return greenio.GreenPipe(os_orig.fdopen(*args, **kw))
|
return greenio.GreenPipe(__original_fdopen__(*args, **kw))
|
||||||
|
|
||||||
|
__original_read__ = os_orig.read
|
||||||
def read(fd, n):
|
def read(fd, n):
|
||||||
"""read(fd, buffersize) -> string
|
"""read(fd, buffersize) -> string
|
||||||
|
|
||||||
Read a file descriptor."""
|
Read a file descriptor."""
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
return os_orig.read(fd, n)
|
return __original_read__(fd, n)
|
||||||
except (OSError, IOError), e:
|
except (OSError, IOError), e:
|
||||||
if e[0] != errno.EAGAIN:
|
if e[0] != errno.EAGAIN:
|
||||||
raise
|
raise
|
||||||
@@ -33,6 +35,7 @@ def read(fd, n):
|
|||||||
raise
|
raise
|
||||||
hubs.trampoline(fd, read=True)
|
hubs.trampoline(fd, read=True)
|
||||||
|
|
||||||
|
__original_write__ = os_orig.write
|
||||||
def write(fd, st):
|
def write(fd, st):
|
||||||
"""write(fd, string) -> byteswritten
|
"""write(fd, string) -> byteswritten
|
||||||
|
|
||||||
@@ -40,7 +43,7 @@ def write(fd, st):
|
|||||||
"""
|
"""
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
return os_orig.write(fd, st)
|
return __original_write__(fd, st)
|
||||||
except (OSError, IOError), e:
|
except (OSError, IOError), e:
|
||||||
if e[0] != errno.EAGAIN:
|
if e[0] != errno.EAGAIN:
|
||||||
raise
|
raise
|
||||||
@@ -55,17 +58,18 @@ def wait():
|
|||||||
Wait for completion of a child process."""
|
Wait for completion of a child process."""
|
||||||
return waitpid(0,0)
|
return waitpid(0,0)
|
||||||
|
|
||||||
|
__original_waitpid__ = os_orig.waitpid
|
||||||
def waitpid(pid, options):
|
def waitpid(pid, options):
|
||||||
"""waitpid(...)
|
"""waitpid(...)
|
||||||
waitpid(pid, options) -> (pid, status)
|
waitpid(pid, options) -> (pid, status)
|
||||||
|
|
||||||
Wait for completion of a given child process."""
|
Wait for completion of a given child process."""
|
||||||
if options & os.WNOHANG != 0:
|
if options & os.WNOHANG != 0:
|
||||||
return os_orig.waitpid(pid, options)
|
return __original_waitpid__(pid, options)
|
||||||
else:
|
else:
|
||||||
new_options = options | os.WNOHANG
|
new_options = options | os.WNOHANG
|
||||||
while True:
|
while True:
|
||||||
rpid, status = os_orig.waitpid(pid, new_options)
|
rpid, status = __original_waitpid__(pid, new_options)
|
||||||
if status >= 0:
|
if status >= 0:
|
||||||
return rpid, status
|
return rpid, status
|
||||||
greenthread.sleep(0.01)
|
greenthread.sleep(0.01)
|
||||||
|
@@ -13,13 +13,16 @@ import warnings
|
|||||||
__patched__ = ['fromfd', 'socketpair', 'gethostbyname', 'create_connection',
|
__patched__ = ['fromfd', 'socketpair', 'gethostbyname', 'create_connection',
|
||||||
'ssl', 'socket']
|
'ssl', 'socket']
|
||||||
|
|
||||||
|
__original_fromfd__ = __socket.fromfd
|
||||||
def fromfd(*args):
|
def fromfd(*args):
|
||||||
return socket(__socket.fromfd(*args))
|
return socket(__original_fromfd__(*args))
|
||||||
|
|
||||||
|
__original_socketpair__ = __socket.socketpair
|
||||||
def socketpair(*args):
|
def socketpair(*args):
|
||||||
one, two = __socket.socketpair(*args)
|
one, two = __original_socketpair__(*args)
|
||||||
return socket(one), socket(two)
|
return socket(one), socket(two)
|
||||||
|
|
||||||
|
__original_gethostbyname__ = __socket.gethostbyname
|
||||||
def gethostbyname(name):
|
def gethostbyname(name):
|
||||||
can_use_tpool = os.environ.get("EVENTLET_TPOOL_GETHOSTBYNAME",
|
can_use_tpool = os.environ.get("EVENTLET_TPOOL_GETHOSTBYNAME",
|
||||||
'').lower() == "yes"
|
'').lower() == "yes"
|
||||||
@@ -28,7 +31,7 @@ def gethostbyname(name):
|
|||||||
elif sys.platform.startswith('darwin') or not can_use_tpool:
|
elif sys.platform.startswith('darwin') or not can_use_tpool:
|
||||||
# the thread primitives on Darwin have some bugs that make
|
# the thread primitives on Darwin have some bugs that make
|
||||||
# it undesirable to use tpool for hostname lookups
|
# it undesirable to use tpool for hostname lookups
|
||||||
globals()['gethostbyname'] = __socket.gethostbyname
|
globals()['gethostbyname'] = __original_gethostbyname__
|
||||||
else:
|
else:
|
||||||
globals()['gethostbyname'] = _gethostbyname_tpool
|
globals()['gethostbyname'] = _gethostbyname_tpool
|
||||||
|
|
||||||
@@ -42,7 +45,7 @@ def _gethostbyname_twisted(name):
|
|||||||
def _gethostbyname_tpool(name):
|
def _gethostbyname_tpool(name):
|
||||||
from eventlet import tpool
|
from eventlet import tpool
|
||||||
return tpool.execute(
|
return tpool.execute(
|
||||||
__socket.gethostbyname, name)
|
__original_gethostbyname__, name)
|
||||||
|
|
||||||
# def getaddrinfo(*args, **kw):
|
# def getaddrinfo(*args, **kw):
|
||||||
# return tpool.execute(
|
# return tpool.execute(
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
"""implements standard module 'thread' with greenlets"""
|
"""implements standard module 'thread' with greenlets"""
|
||||||
__thread = __import__('thread')
|
__thread = __import__('thread')
|
||||||
from eventlet.support import greenlets as greenlet
|
from eventlet.support import greenlets as greenlet
|
||||||
from eventlet.api import spawn
|
from eventlet import greenthread
|
||||||
from eventlet.semaphore import Semaphore as LockType
|
from eventlet.semaphore import Semaphore as LockType
|
||||||
|
|
||||||
__patched__ = ['get_ident', 'start_new_thread', 'start_new', 'allocate_lock',
|
__patched__ = ['get_ident', 'start_new_thread', 'start_new', 'allocate_lock',
|
||||||
'allocate', 'exit', 'interrupt_main', 'stack_size', '_local']
|
'allocate', 'exit', 'interrupt_main', 'stack_size', '_local', 'LockType']
|
||||||
|
|
||||||
error = __thread.error
|
error = __thread.error
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ def get_ident(gr=None):
|
|||||||
return id(gr)
|
return id(gr)
|
||||||
|
|
||||||
def start_new_thread(function, args=(), kwargs={}):
|
def start_new_thread(function, args=(), kwargs={}):
|
||||||
g = spawn(function, *args, **kwargs)
|
g = greenthread.spawn(function, *args, **kwargs)
|
||||||
return get_ident(g)
|
return get_ident(g)
|
||||||
|
|
||||||
start_new = start_new_thread
|
start_new = start_new_thread
|
||||||
@@ -38,12 +38,13 @@ def interrupt_main():
|
|||||||
else:
|
else:
|
||||||
raise KeyboardInterrupt()
|
raise KeyboardInterrupt()
|
||||||
|
|
||||||
|
__original_stack_size__ = __thread.stack_size
|
||||||
if hasattr(__thread, 'stack_size'):
|
if hasattr(__thread, 'stack_size'):
|
||||||
def stack_size(size=None):
|
def stack_size(size=None):
|
||||||
if size is None:
|
if size is None:
|
||||||
return __thread.stack_size()
|
return __original_stack_size__()
|
||||||
if size > __thread.stack_size():
|
if size > __original_stack_size__():
|
||||||
return __thread.stack_size(size)
|
return __original_stack_size__(size)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
# not going to decrease stack_size, because otherwise other greenlets in this thread will suffer
|
# not going to decrease stack_size, because otherwise other greenlets in this thread will suffer
|
||||||
|
@@ -2,6 +2,8 @@ from eventlet import patcher
|
|||||||
from eventlet.green import thread
|
from eventlet.green import thread
|
||||||
from eventlet.green import time
|
from eventlet.green import time
|
||||||
|
|
||||||
|
__patched__ = ['_start_new_thread', '_allocate_lock', '_get_ident']
|
||||||
|
|
||||||
patcher.inject('threading',
|
patcher.inject('threading',
|
||||||
globals(),
|
globals(),
|
||||||
('thread', thread),
|
('thread', thread),
|
||||||
|
@@ -142,7 +142,8 @@ def _green_socket_modules():
|
|||||||
def _green_thread_modules():
|
def _green_thread_modules():
|
||||||
from eventlet.green import Queue
|
from eventlet.green import Queue
|
||||||
from eventlet.green import thread
|
from eventlet.green import thread
|
||||||
return [('Queue', Queue), ('thread', thread)]
|
from eventlet.green import threading
|
||||||
|
return [('Queue', Queue), ('thread', thread), ('threading', threading)]
|
||||||
|
|
||||||
def _green_time_modules():
|
def _green_time_modules():
|
||||||
from eventlet.green import time
|
from eventlet.green import time
|
||||||
|
@@ -22,6 +22,7 @@ in :meth:`put <Queue.put>` or :meth:`get <Queue.get>` respectively.
|
|||||||
import sys
|
import sys
|
||||||
import heapq
|
import heapq
|
||||||
import collections
|
import collections
|
||||||
|
import traceback
|
||||||
from Queue import Full, Empty
|
from Queue import Full, Empty
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@ Many of these tests make connections to external servers, and all.py tries to sk
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def import_main(name):
|
def assimilate_patched(name):
|
||||||
try:
|
try:
|
||||||
modobj = __import__(name, globals(), locals(), ['test_main'])
|
modobj = __import__(name, globals(), locals(), ['test_main'])
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -18,44 +18,7 @@ def import_main(name):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
print "No test_main for %s, assuming it tests on import" % name
|
print "No test_main for %s, assuming it tests on import" % name
|
||||||
|
|
||||||
|
import all_modules
|
||||||
|
|
||||||
# quick and dirty way of testing whether we can access
|
for m in all_modules.get_modules():
|
||||||
# remote hosts; any tests that try internet connections
|
assimilate_patched(m)
|
||||||
# will fail if we cannot
|
|
||||||
import socket
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
try:
|
|
||||||
s.settimeout(0.5)
|
|
||||||
s.connect(('eventlet.net', 80))
|
|
||||||
s.close()
|
|
||||||
have_network_access = True
|
|
||||||
except socket.error, e:
|
|
||||||
print "Skipping network tests"
|
|
||||||
have_network_access = False
|
|
||||||
|
|
||||||
import_main('test_select')
|
|
||||||
import_main('test_SimpleHTTPServer')
|
|
||||||
import_main('test_asynchat')
|
|
||||||
import_main('test_asyncore')
|
|
||||||
import_main('test_ftplib')
|
|
||||||
import_main('test_httplib')
|
|
||||||
if have_network_access:
|
|
||||||
import_main('test_httpservers')
|
|
||||||
import_main('test_os')
|
|
||||||
import_main('test_queue')
|
|
||||||
if have_network_access:
|
|
||||||
import_main('test_socket')
|
|
||||||
import_main('test_socket_ssl')
|
|
||||||
#import_main('test_socketserver')
|
|
||||||
#import_main('test_subprocess')
|
|
||||||
if have_network_access:
|
|
||||||
import_main('test_ssl')
|
|
||||||
import_main('test_thread')
|
|
||||||
#import_main('test_threading')
|
|
||||||
import_main('test_threading_local')
|
|
||||||
if have_network_access:
|
|
||||||
import_main('test_timeout')
|
|
||||||
import_main('test_urllib')
|
|
||||||
if have_network_access:
|
|
||||||
import_main('test_urllib2')
|
|
||||||
import_main('test_urllib2_localnet')
|
|
||||||
|
41
tests/stdlib/all_modules.py
Normal file
41
tests/stdlib/all_modules.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
def get_modules():
|
||||||
|
test_modules = [
|
||||||
|
'test_select',
|
||||||
|
'test_SimpleHTTPServer',
|
||||||
|
'test_asynchat',
|
||||||
|
'test_asyncore',
|
||||||
|
'test_ftplib',
|
||||||
|
'test_httplib',
|
||||||
|
'test_os',
|
||||||
|
'test_queue',
|
||||||
|
'test_socket_ssl',
|
||||||
|
# 'test_socketserver',
|
||||||
|
# 'test_subprocess',
|
||||||
|
'test_thread',
|
||||||
|
# 'test_threading',
|
||||||
|
'test_threading_local',
|
||||||
|
'test_urllib',
|
||||||
|
'test_urllib2_localnet']
|
||||||
|
|
||||||
|
network_modules = [
|
||||||
|
'test_httpservers',
|
||||||
|
'test_socket',
|
||||||
|
'test_ssl',
|
||||||
|
'test_timeout',
|
||||||
|
'test_urllib2']
|
||||||
|
|
||||||
|
# quick and dirty way of testing whether we can access
|
||||||
|
# remote hosts; any tests that try internet connections
|
||||||
|
# will fail if we cannot
|
||||||
|
import socket
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
try:
|
||||||
|
s.settimeout(0.5)
|
||||||
|
s.connect(('eventlet.net', 80))
|
||||||
|
s.close()
|
||||||
|
test_modules = test_modules + network_modules
|
||||||
|
except socket.error, e:
|
||||||
|
print "Skipping network tests"
|
||||||
|
|
||||||
|
return test_modules
|
||||||
|
|
24
tests/stdlib/all_monkey.py
Normal file
24
tests/stdlib/all_monkey.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import eventlet
|
||||||
|
eventlet.sleep(0)
|
||||||
|
from eventlet import patcher
|
||||||
|
patcher.monkey_patch()
|
||||||
|
|
||||||
|
def assimilate_real(name):
|
||||||
|
print "Assimilating", name
|
||||||
|
try:
|
||||||
|
modobj = __import__('test.' + name, globals(), locals(), ['test_main'])
|
||||||
|
except ImportError:
|
||||||
|
print "Not importing %s, it doesn't exist in this installation/version of Python" % name
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
method_name = name + "_test_main"
|
||||||
|
try:
|
||||||
|
globals()[method_name] = modobj.test_main
|
||||||
|
modobj.test_main.__name__ = name + '.test_main'
|
||||||
|
except AttributeError:
|
||||||
|
print "No test_main for %s, assuming it tests on import" % name
|
||||||
|
|
||||||
|
import all_modules
|
||||||
|
|
||||||
|
for m in all_modules.get_modules():
|
||||||
|
assimilate_real(m)
|
Reference in New Issue
Block a user