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):
|
||||
exec "%s = os_orig.%s" % (var, var)
|
||||
|
||||
__original_fdopen__ = os_orig.fdopen
|
||||
def fdopen(*args, **kw):
|
||||
"""fdopen(fd [, mode='r' [, bufsize]]) -> file_object
|
||||
|
||||
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):
|
||||
"""read(fd, buffersize) -> string
|
||||
|
||||
Read a file descriptor."""
|
||||
while True:
|
||||
try:
|
||||
return os_orig.read(fd, n)
|
||||
return __original_read__(fd, n)
|
||||
except (OSError, IOError), e:
|
||||
if e[0] != errno.EAGAIN:
|
||||
raise
|
||||
@@ -33,6 +35,7 @@ def read(fd, n):
|
||||
raise
|
||||
hubs.trampoline(fd, read=True)
|
||||
|
||||
__original_write__ = os_orig.write
|
||||
def write(fd, st):
|
||||
"""write(fd, string) -> byteswritten
|
||||
|
||||
@@ -40,7 +43,7 @@ def write(fd, st):
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
return os_orig.write(fd, st)
|
||||
return __original_write__(fd, st)
|
||||
except (OSError, IOError), e:
|
||||
if e[0] != errno.EAGAIN:
|
||||
raise
|
||||
@@ -55,17 +58,18 @@ def wait():
|
||||
Wait for completion of a child process."""
|
||||
return waitpid(0,0)
|
||||
|
||||
__original_waitpid__ = os_orig.waitpid
|
||||
def waitpid(pid, options):
|
||||
"""waitpid(...)
|
||||
waitpid(pid, options) -> (pid, status)
|
||||
|
||||
Wait for completion of a given child process."""
|
||||
if options & os.WNOHANG != 0:
|
||||
return os_orig.waitpid(pid, options)
|
||||
return __original_waitpid__(pid, options)
|
||||
else:
|
||||
new_options = options | os.WNOHANG
|
||||
while True:
|
||||
rpid, status = os_orig.waitpid(pid, new_options)
|
||||
rpid, status = __original_waitpid__(pid, new_options)
|
||||
if status >= 0:
|
||||
return rpid, status
|
||||
greenthread.sleep(0.01)
|
||||
|
@@ -13,13 +13,16 @@ import warnings
|
||||
__patched__ = ['fromfd', 'socketpair', 'gethostbyname', 'create_connection',
|
||||
'ssl', 'socket']
|
||||
|
||||
__original_fromfd__ = __socket.fromfd
|
||||
def fromfd(*args):
|
||||
return socket(__socket.fromfd(*args))
|
||||
return socket(__original_fromfd__(*args))
|
||||
|
||||
__original_socketpair__ = __socket.socketpair
|
||||
def socketpair(*args):
|
||||
one, two = __socket.socketpair(*args)
|
||||
one, two = __original_socketpair__(*args)
|
||||
return socket(one), socket(two)
|
||||
|
||||
__original_gethostbyname__ = __socket.gethostbyname
|
||||
def gethostbyname(name):
|
||||
can_use_tpool = os.environ.get("EVENTLET_TPOOL_GETHOSTBYNAME",
|
||||
'').lower() == "yes"
|
||||
@@ -28,7 +31,7 @@ def gethostbyname(name):
|
||||
elif sys.platform.startswith('darwin') or not can_use_tpool:
|
||||
# the thread primitives on Darwin have some bugs that make
|
||||
# it undesirable to use tpool for hostname lookups
|
||||
globals()['gethostbyname'] = __socket.gethostbyname
|
||||
globals()['gethostbyname'] = __original_gethostbyname__
|
||||
else:
|
||||
globals()['gethostbyname'] = _gethostbyname_tpool
|
||||
|
||||
@@ -42,7 +45,7 @@ def _gethostbyname_twisted(name):
|
||||
def _gethostbyname_tpool(name):
|
||||
from eventlet import tpool
|
||||
return tpool.execute(
|
||||
__socket.gethostbyname, name)
|
||||
__original_gethostbyname__, name)
|
||||
|
||||
# def getaddrinfo(*args, **kw):
|
||||
# return tpool.execute(
|
||||
|
@@ -1,11 +1,11 @@
|
||||
"""implements standard module 'thread' with greenlets"""
|
||||
__thread = __import__('thread')
|
||||
from eventlet.support import greenlets as greenlet
|
||||
from eventlet.api import spawn
|
||||
from eventlet import greenthread
|
||||
from eventlet.semaphore import Semaphore as LockType
|
||||
|
||||
__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
|
||||
|
||||
@@ -16,7 +16,7 @@ def get_ident(gr=None):
|
||||
return id(gr)
|
||||
|
||||
def start_new_thread(function, args=(), kwargs={}):
|
||||
g = spawn(function, *args, **kwargs)
|
||||
g = greenthread.spawn(function, *args, **kwargs)
|
||||
return get_ident(g)
|
||||
|
||||
start_new = start_new_thread
|
||||
@@ -38,12 +38,13 @@ def interrupt_main():
|
||||
else:
|
||||
raise KeyboardInterrupt()
|
||||
|
||||
__original_stack_size__ = __thread.stack_size
|
||||
if hasattr(__thread, 'stack_size'):
|
||||
def stack_size(size=None):
|
||||
if size is None:
|
||||
return __thread.stack_size()
|
||||
if size > __thread.stack_size():
|
||||
return __thread.stack_size(size)
|
||||
return __original_stack_size__()
|
||||
if size > __original_stack_size__():
|
||||
return __original_stack_size__(size)
|
||||
else:
|
||||
pass
|
||||
# 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 time
|
||||
|
||||
__patched__ = ['_start_new_thread', '_allocate_lock', '_get_ident']
|
||||
|
||||
patcher.inject('threading',
|
||||
globals(),
|
||||
('thread', thread),
|
||||
|
@@ -142,7 +142,8 @@ def _green_socket_modules():
|
||||
def _green_thread_modules():
|
||||
from eventlet.green import Queue
|
||||
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():
|
||||
from eventlet.green import time
|
||||
|
@@ -22,6 +22,7 @@ in :meth:`put <Queue.put>` or :meth:`get <Queue.get>` respectively.
|
||||
import sys
|
||||
import heapq
|
||||
import collections
|
||||
import traceback
|
||||
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:
|
||||
modobj = __import__(name, globals(), locals(), ['test_main'])
|
||||
except ImportError:
|
||||
@@ -18,44 +18,7 @@ def import_main(name):
|
||||
except AttributeError:
|
||||
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
|
||||
# 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()
|
||||
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')
|
||||
for m in all_modules.get_modules():
|
||||
assimilate_patched(m)
|
||||
|
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