Merge
This commit is contained in:
2
AUTHORS
2
AUTHORS
@@ -26,7 +26,7 @@ Thanks To
|
|||||||
* Chuck Thier, reporting a bug in processes.py
|
* Chuck Thier, reporting a bug in processes.py
|
||||||
* Brantley Harris, reporting bug #4
|
* Brantley Harris, reporting bug #4
|
||||||
* Taso Du Val, reproing an exception squelching bug, saving children's lives ;-)
|
* Taso Du Val, reproing an exception squelching bug, saving children's lives ;-)
|
||||||
* R. Tyler Ballance, bug report on tpool on Windows, help with improving corolocal module
|
* R. Tyler Ballance, bug report on tpool on Windows, help with improving corolocal module, profile performance report, suggestion use flush that fixed tpool on Windows
|
||||||
* Sergey Shepelev, PEP 8 police :-), reporting bug #5
|
* Sergey Shepelev, PEP 8 police :-), reporting bug #5
|
||||||
* Luci Stanescu, for reporting twisted hub bug
|
* Luci Stanescu, for reporting twisted hub bug
|
||||||
* Marcus Cavanaugh, for test case code that has been incredibly useful in tracking down bugs
|
* Marcus Cavanaugh, for test case code that has been incredibly useful in tracking down bugs
|
||||||
|
4
NEWS
4
NEWS
@@ -13,7 +13,9 @@
|
|||||||
* Added support for logging x-forwarded-for header in wsgi.
|
* Added support for logging x-forwarded-for header in wsgi.
|
||||||
* api.tcp_server is now deprecated, will be removed in a future release.
|
* api.tcp_server is now deprecated, will be removed in a future release.
|
||||||
* Added instructions on how to generate coverage reports to the documentation.
|
* Added instructions on how to generate coverage reports to the documentation.
|
||||||
* Bug fixes in: wsgi.py, twistedr.py, poll.py, greenio.py, util.py, select.py, processes.py
|
* Renamed GreenFile to Green_fileobject, to better reflect its purpose.
|
||||||
|
* Deprecated erpc method in tpool.py
|
||||||
|
* Bug fixes in: wsgi.py, twistedr.py, poll.py, greenio.py, util.py, select.py, processes.py, selects.py
|
||||||
|
|
||||||
0.9.0
|
0.9.0
|
||||||
=====
|
=====
|
||||||
|
@@ -35,7 +35,7 @@ easy_install eventlet
|
|||||||
|
|
||||||
<p>Alternately, you can download the source tarball:
|
<p>Alternately, you can download the source tarball:
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://pypi.python.org/packages/source/e/eventlet/eventlet-0.9.0.tar.gz#md5=4e14ce5070edd078e3a4e8d6df9a5dc4">eventlet-0.9.0.tar.gz</a></li>
|
<li><a href="http://pypi.python.org/packages/source/e/eventlet/eventlet-0.9.1.tar.gz">eventlet-0.9.1.tar.gz</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
version_info = (0, 9, '1pre')
|
version_info = (0, 9, 1)
|
||||||
__version__ = '%s.%s.%s' % version_info
|
__version__ = '%s.%s.%s' % version_info
|
||||||
|
@@ -11,12 +11,23 @@ from thread import get_ident
|
|||||||
from eventlet.greenio import set_nonblocking, GreenSocket, SOCKET_CLOSED, CONNECT_ERR, CONNECT_SUCCESS
|
from eventlet.greenio import set_nonblocking, GreenSocket, SOCKET_CLOSED, CONNECT_ERR, CONNECT_SUCCESS
|
||||||
orig_socket = __import__('socket')
|
orig_socket = __import__('socket')
|
||||||
socket = orig_socket.socket
|
socket = orig_socket.socket
|
||||||
|
timeout_exc = orig_socket.timeout
|
||||||
|
|
||||||
|
|
||||||
class GreenSSLSocket(__ssl.SSLSocket):
|
class GreenSSLSocket(__ssl.SSLSocket):
|
||||||
""" This is a green version of the SSLSocket class from the ssl module added
|
""" This is a green version of the SSLSocket class from the ssl module added
|
||||||
in 2.6. For documentation on it, please see the Python standard
|
in 2.6. For documentation on it, please see the Python standard
|
||||||
documentation."""
|
documentation.
|
||||||
|
|
||||||
|
Python nonblocking ssl objects don't give errors when the other end
|
||||||
|
of the socket is closed (they do notice when the other end is shutdown,
|
||||||
|
though). Any write/read operations will simply hang if the socket is
|
||||||
|
closed from the other end. There is no obvious fix for this problem;
|
||||||
|
it appears to be a limitation of Python's ssl object implementation.
|
||||||
|
A workaround is to set a reasonable timeout on the socket using
|
||||||
|
settimeout(), and to close/reopen the connection when a timeout
|
||||||
|
occurs at an unexpected juncture in the code.
|
||||||
|
"""
|
||||||
# we are inheriting from SSLSocket because its constructor calls
|
# we are inheriting from SSLSocket because its constructor calls
|
||||||
# do_handshake whose behavior we wish to override
|
# do_handshake whose behavior we wish to override
|
||||||
def __init__(self, sock, *args, **kw):
|
def __init__(self, sock, *args, **kw):
|
||||||
@@ -62,12 +73,12 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
|||||||
trampoline(self.fileno(),
|
trampoline(self.fileno(),
|
||||||
read=True,
|
read=True,
|
||||||
timeout=self.gettimeout(),
|
timeout=self.gettimeout(),
|
||||||
timeout_exc=SSLError)
|
timeout_exc=timeout_exc('timed out'))
|
||||||
elif exc[0] == SSL_ERROR_WANT_WRITE:
|
elif exc[0] == SSL_ERROR_WANT_WRITE:
|
||||||
trampoline(self.fileno(),
|
trampoline(self.fileno(),
|
||||||
write=True,
|
write=True,
|
||||||
timeout=self.gettimeout(),
|
timeout=self.gettimeout(),
|
||||||
timeout_exc=SSLError)
|
timeout_exc=timeout_exc('timed out'))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -121,7 +132,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
|||||||
raise ValueError("sendto not allowed on instances of %s" %
|
raise ValueError("sendto not allowed on instances of %s" %
|
||||||
self.__class__)
|
self.__class__)
|
||||||
else:
|
else:
|
||||||
trampoline(self.fileno(), write=True, timeout_exc=orig_socket.timeout)
|
trampoline(self.fileno(), write=True, timeout_exc=timeout_exc('timed out'))
|
||||||
return socket.sendto(self, data, addr, flags)
|
return socket.sendto(self, data, addr, flags)
|
||||||
|
|
||||||
def sendall (self, data, flags=0):
|
def sendall (self, data, flags=0):
|
||||||
@@ -146,7 +157,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
|||||||
raise
|
raise
|
||||||
if e[0] == errno.EWOULDBLOCK:
|
if e[0] == errno.EWOULDBLOCK:
|
||||||
trampoline(self.fileno(), write=True,
|
trampoline(self.fileno(), write=True,
|
||||||
timeout=self.gettimeout(), timeout_exc=orig_socket.timeout)
|
timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||||
if e[0] in SOCKET_CLOSED:
|
if e[0] in SOCKET_CLOSED:
|
||||||
return ''
|
return ''
|
||||||
raise
|
raise
|
||||||
@@ -169,7 +180,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
|||||||
raise
|
raise
|
||||||
if e[0] == errno.EWOULDBLOCK:
|
if e[0] == errno.EWOULDBLOCK:
|
||||||
trampoline(self.fileno(), read=True,
|
trampoline(self.fileno(), read=True,
|
||||||
timeout=self.gettimeout(), timeout_exc=orig_socket.timeout)
|
timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||||
if e[0] in SOCKET_CLOSED:
|
if e[0] in SOCKET_CLOSED:
|
||||||
return ''
|
return ''
|
||||||
raise
|
raise
|
||||||
@@ -177,17 +188,17 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
|||||||
|
|
||||||
def recv_into (self, buffer, nbytes=None, flags=0):
|
def recv_into (self, buffer, nbytes=None, flags=0):
|
||||||
if not self.act_non_blocking:
|
if not self.act_non_blocking:
|
||||||
trampoline(self.fileno(), read=True, timeout=self.gettimeout(), timeout_exc=orig_socket.timeout)
|
trampoline(self.fileno(), read=True, timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||||
return super(GreenSSLSocket, self).recv_into(buffer, nbytes, flags)
|
return super(GreenSSLSocket, self).recv_into(buffer, nbytes, flags)
|
||||||
|
|
||||||
def recvfrom (self, addr, buflen=1024, flags=0):
|
def recvfrom (self, addr, buflen=1024, flags=0):
|
||||||
if not self.act_non_blocking:
|
if not self.act_non_blocking:
|
||||||
trampoline(self.fileno(), read=True, timeout=self.gettimeout(), timeout_exc=orig_socket.timeout)
|
trampoline(self.fileno(), read=True, timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||||
return super(GreenSSLSocket, self).recvfrom(addr, buflen, flags)
|
return super(GreenSSLSocket, self).recvfrom(addr, buflen, flags)
|
||||||
|
|
||||||
def recvfrom_into (self, buffer, nbytes=None, flags=0):
|
def recvfrom_into (self, buffer, nbytes=None, flags=0):
|
||||||
if not self.act_non_blocking:
|
if not self.act_non_blocking:
|
||||||
trampoline(self.fileno(), read=True, timeout=self.gettimeout(), timeout_exc=orig_socket.timeout)
|
trampoline(self.fileno(), read=True, timeout=self.gettimeout(), timeout_exc=timeout_exc('timed out'))
|
||||||
return super(GreenSSLSocket, self).recvfrom_into(buffer, nbytes, flags)
|
return super(GreenSSLSocket, self).recvfrom_into(buffer, nbytes, flags)
|
||||||
|
|
||||||
def unwrap(self):
|
def unwrap(self):
|
||||||
@@ -224,13 +235,13 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
|||||||
except orig_socket.error, exc:
|
except orig_socket.error, exc:
|
||||||
if exc[0] in CONNECT_ERR:
|
if exc[0] in CONNECT_ERR:
|
||||||
trampoline(self.fileno(), write=True,
|
trampoline(self.fileno(), write=True,
|
||||||
timeout=end-time.time(), timeout_exc=orig_socket.timeout)
|
timeout=end-time.time(), timeout_exc=timeout_exc('timed out'))
|
||||||
elif exc[0] in CONNECT_SUCCESS:
|
elif exc[0] in CONNECT_SUCCESS:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
if time.time() >= end:
|
if time.time() >= end:
|
||||||
raise orig_socket.timeout
|
raise timeout_exc('timed out')
|
||||||
|
|
||||||
|
|
||||||
def connect(self, addr):
|
def connect(self, addr):
|
||||||
@@ -264,7 +275,7 @@ class GreenSSLSocket(__ssl.SSLSocket):
|
|||||||
if e[0] != errno.EWOULDBLOCK:
|
if e[0] != errno.EWOULDBLOCK:
|
||||||
raise
|
raise
|
||||||
trampoline(self.fileno(), read=True, timeout=self.gettimeout(),
|
trampoline(self.fileno(), read=True, timeout=self.gettimeout(),
|
||||||
timeout_exc=orig_socket.timeout)
|
timeout_exc=timeout_exc('timed out'))
|
||||||
|
|
||||||
new_ssl = type(self)(newsock,
|
new_ssl = type(self)(newsock,
|
||||||
keyfile=self.keyfile,
|
keyfile=self.keyfile,
|
||||||
|
@@ -14,7 +14,7 @@ import warnings
|
|||||||
from errno import EWOULDBLOCK, EAGAIN
|
from errno import EWOULDBLOCK, EAGAIN
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['GreenSocket', 'GreenFile', 'GreenPipe']
|
__all__ = ['GreenSocket', 'GreenPipe']
|
||||||
|
|
||||||
def higher_order_recv(recv_func):
|
def higher_order_recv(recv_func):
|
||||||
def recv(self, buflen, flags=0):
|
def recv(self, buflen, flags=0):
|
||||||
@@ -167,6 +167,10 @@ class GreenSocket(object):
|
|||||||
fd = family_or_realsock
|
fd = family_or_realsock
|
||||||
assert not args, args
|
assert not args, args
|
||||||
assert not kwargs, kwargs
|
assert not kwargs, kwargs
|
||||||
|
try:
|
||||||
|
orig_timeout = fd.gettimeout()
|
||||||
|
except AttributeError:
|
||||||
|
orig_timeout = None
|
||||||
|
|
||||||
set_nonblocking(fd)
|
set_nonblocking(fd)
|
||||||
self.fd = fd
|
self.fd = fd
|
||||||
@@ -181,6 +185,10 @@ class GreenSocket(object):
|
|||||||
# act non-blocking
|
# act non-blocking
|
||||||
self.act_non_blocking = False
|
self.act_non_blocking = False
|
||||||
|
|
||||||
|
# import timeout from the other fd if it's distinct
|
||||||
|
if orig_timeout and orig_timeout is not self.timeout:
|
||||||
|
self.settimeout(orig_timeout)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _sock(self):
|
def _sock(self):
|
||||||
return self
|
return self
|
||||||
@@ -294,7 +302,7 @@ class GreenSocket(object):
|
|||||||
return socket._fileobject(self.dup(), mode, bufsize)
|
return socket._fileobject(self.dup(), mode, bufsize)
|
||||||
|
|
||||||
def makeGreenFile(self, mode='r', bufsize=-1):
|
def makeGreenFile(self, mode='r', bufsize=-1):
|
||||||
return GreenFile(self.dup())
|
return Green_fileobject(self.dup())
|
||||||
|
|
||||||
recv = higher_order_recv(socket_recv)
|
recv = higher_order_recv(socket_recv)
|
||||||
|
|
||||||
@@ -362,8 +370,9 @@ class GreenSocket(object):
|
|||||||
return self.timeout
|
return self.timeout
|
||||||
|
|
||||||
|
|
||||||
|
class Green_fileobject(object):
|
||||||
class GreenFile(object):
|
"""Green version of socket._fileobject, for use only with regular
|
||||||
|
sockets."""
|
||||||
newlines = '\r\n'
|
newlines = '\r\n'
|
||||||
mode = 'wb+'
|
mode = 'wb+'
|
||||||
|
|
||||||
@@ -486,7 +495,7 @@ class GreenPipeSocket(GreenSocket):
|
|||||||
send = higher_order_send(file_send)
|
send = higher_order_send(file_send)
|
||||||
|
|
||||||
|
|
||||||
class GreenPipe(GreenFile):
|
class GreenPipe(Green_fileobject):
|
||||||
def __init__(self, fd):
|
def __init__(self, fd):
|
||||||
set_nonblocking(fd)
|
set_nonblocking(fd)
|
||||||
self.fd = GreenPipeSocket(fd)
|
self.fd = GreenPipeSocket(fd)
|
||||||
|
@@ -61,6 +61,7 @@ class BaseHub(object):
|
|||||||
'exit': [],
|
'exit': [],
|
||||||
}
|
}
|
||||||
self.lclass = FdListener
|
self.lclass = FdListener
|
||||||
|
self.silent_timer_exceptions = False
|
||||||
|
|
||||||
def add(self, evtype, fileno, cb):
|
def add(self, evtype, fileno, cb):
|
||||||
""" Signals an intent to or write a particular file descriptor.
|
""" Signals an intent to or write a particular file descriptor.
|
||||||
@@ -220,6 +221,7 @@ class BaseHub(object):
|
|||||||
self.squelch_observer_exception(observer, sys.exc_info())
|
self.squelch_observer_exception(observer, sys.exc_info())
|
||||||
|
|
||||||
def squelch_timer_exception(self, timer, exc_info):
|
def squelch_timer_exception(self, timer, exc_info):
|
||||||
|
if not self.silent_timer_exceptions:
|
||||||
traceback.print_exception(*exc_info)
|
traceback.print_exception(*exc_info)
|
||||||
print >>sys.stderr, "Timer raised: %r" % (timer,)
|
print >>sys.stderr, "Timer raised: %r" % (timer,)
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@ import time
|
|||||||
from eventlet.hubs.hub import BaseHub, READ, WRITE
|
from eventlet.hubs.hub import BaseHub, READ, WRITE
|
||||||
|
|
||||||
EXC_MASK = select.POLLERR | select.POLLHUP
|
EXC_MASK = select.POLLERR | select.POLLHUP
|
||||||
READ_MASK = select.POLLIN
|
READ_MASK = select.POLLIN | select.POLLPRI
|
||||||
WRITE_MASK = select.POLLOUT
|
WRITE_MASK = select.POLLOUT
|
||||||
|
|
||||||
class Hub(BaseHub):
|
class Hub(BaseHub):
|
||||||
|
@@ -25,8 +25,8 @@ QUIET=False
|
|||||||
_rfile = _wfile = None
|
_rfile = _wfile = None
|
||||||
|
|
||||||
def _signal_t2e():
|
def _signal_t2e():
|
||||||
from eventlet import util
|
_wfile.write(' ')
|
||||||
sent = util.__original_write__(_wfile.fileno(), ' ')
|
_wfile.flush()
|
||||||
|
|
||||||
_reqq = Queue(maxsize=-1)
|
_reqq = Queue(maxsize=-1)
|
||||||
_rspq = Queue(maxsize=-1)
|
_rspq = Queue(maxsize=-1)
|
||||||
@@ -36,9 +36,9 @@ def tpool_trampoline():
|
|||||||
while(True):
|
while(True):
|
||||||
try:
|
try:
|
||||||
_c = _rfile.read(1)
|
_c = _rfile.read(1)
|
||||||
|
assert(_c != "")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
break # will be raised when pipe is closed
|
break # will be raised when pipe is closed
|
||||||
assert(_c != "")
|
|
||||||
while not _rspq.empty():
|
while not _rspq.empty():
|
||||||
try:
|
try:
|
||||||
(e,rv) = _rspq.get(block=False)
|
(e,rv) = _rspq.get(block=False)
|
||||||
@@ -197,10 +197,8 @@ def setup():
|
|||||||
sock.listen(50)
|
sock.listen(50)
|
||||||
csock = util.__original_socket__(socket.AF_INET, socket.SOCK_STREAM)
|
csock = util.__original_socket__(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
csock.connect(('localhost', sock.getsockname()[1]))
|
csock.connect(('localhost', sock.getsockname()[1]))
|
||||||
csock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
|
||||||
nsock, addr = sock.accept()
|
nsock, addr = sock.accept()
|
||||||
nsock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
_rfile = greenio.Green_fileobject(greenio.GreenSocket(csock))
|
||||||
_rfile = greenio.GreenFile(greenio.GreenSocket(csock))
|
|
||||||
_wfile = nsock.makefile()
|
_wfile = nsock.makefile()
|
||||||
|
|
||||||
for i in range(0,_nthreads):
|
for i in range(0,_nthreads):
|
||||||
@@ -218,6 +216,7 @@ def killall():
|
|||||||
_reqq.put(None)
|
_reqq.put(None)
|
||||||
for thr in _threads.values():
|
for thr in _threads.values():
|
||||||
thr.join()
|
thr.join()
|
||||||
|
if _coro:
|
||||||
api.kill(_coro)
|
api.kill(_coro)
|
||||||
_rfile.close()
|
_rfile.close()
|
||||||
_wfile.close()
|
_wfile.close()
|
||||||
|
@@ -154,7 +154,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
except greenio.SSL.ZeroReturnError:
|
except greenio.SSL.ZeroReturnError:
|
||||||
self.raw_requestline = ''
|
self.raw_requestline = ''
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
if e[0] != errno.EBADF:
|
if e[0] != errno.EBADF and e[0] != 10053:
|
||||||
raise
|
raise
|
||||||
self.raw_requestline = ''
|
self.raw_requestline = ''
|
||||||
|
|
||||||
@@ -261,11 +261,14 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
'Content-Length' not in [h for h, v in headers_set[1]]:
|
'Content-Length' not in [h for h, v in headers_set[1]]:
|
||||||
headers_set[1].append(('Content-Length', str(sum(map(len, result)))))
|
headers_set[1].append(('Content-Length', str(sum(map(len, result)))))
|
||||||
towrite = []
|
towrite = []
|
||||||
|
towrite_size = 0
|
||||||
for data in result:
|
for data in result:
|
||||||
towrite.append(data)
|
towrite.append(data)
|
||||||
if sum(map(len, towrite)) >= self.minimum_chunk_size:
|
towrite_size += len(data)
|
||||||
|
if towrite_size >= self.minimum_chunk_size:
|
||||||
write(''.join(towrite))
|
write(''.join(towrite))
|
||||||
towrite = []
|
towrite = []
|
||||||
|
towrite_size = 0
|
||||||
if towrite:
|
if towrite:
|
||||||
write(''.join(towrite))
|
write(''.join(towrite))
|
||||||
if not headers_sent or use_chunked[0]:
|
if not headers_sent or use_chunked[0]:
|
||||||
|
@@ -4,6 +4,9 @@ import os
|
|||||||
import errno
|
import errno
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
# convenience
|
||||||
|
main = unittest.main
|
||||||
|
|
||||||
def skipped(func):
|
def skipped(func):
|
||||||
""" Decorator that marks a function as skipped. Uses nose's SkipTest exception
|
""" Decorator that marks a function as skipped. Uses nose's SkipTest exception
|
||||||
if installed. Without nose, this will count skipped tests as passing tests."""
|
if installed. Without nose, this will count skipped tests as passing tests."""
|
||||||
@@ -21,21 +24,36 @@ def skipped(func):
|
|||||||
return skipme
|
return skipme
|
||||||
|
|
||||||
|
|
||||||
def skip_unless(requirement):
|
def skip_if(condition):
|
||||||
""" Decorator that skips a test if the *requirement* does not return True.
|
""" Decorator that skips a test if the *condition* evaluates True.
|
||||||
*requirement* can be a boolean or a callable that accepts one argument.
|
*condition* can be a boolean or a callable that accepts one argument.
|
||||||
The callable will be called with the function to be decorated, and
|
The callable will be called with the function to be decorated, and
|
||||||
should return True if the requirement is satisfied.
|
should return True to skip the test.
|
||||||
"""
|
"""
|
||||||
if isinstance(requirement, bool):
|
|
||||||
def skipped_wrapper(func):
|
def skipped_wrapper(func):
|
||||||
if not requirement:
|
if isinstance(condition, bool):
|
||||||
|
result = condition
|
||||||
|
else:
|
||||||
|
result = condition(func)
|
||||||
|
if result:
|
||||||
return skipped(func)
|
return skipped(func)
|
||||||
else:
|
else:
|
||||||
return func
|
return func
|
||||||
else:
|
return skipped_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def skip_unless(condition):
|
||||||
|
""" Decorator that skips a test if the *condition* does not return True.
|
||||||
|
*condition* can be a boolean or a callable that accepts one argument.
|
||||||
|
The callable will be called with the function to be decorated, and
|
||||||
|
should return True if the condition is satisfied.
|
||||||
|
"""
|
||||||
def skipped_wrapper(func):
|
def skipped_wrapper(func):
|
||||||
if not requirement(func):
|
if isinstance(condition, bool):
|
||||||
|
result = condition
|
||||||
|
else:
|
||||||
|
result = condition(func)
|
||||||
|
if not result:
|
||||||
return skipped(func)
|
return skipped(func)
|
||||||
else:
|
else:
|
||||||
return func
|
return func
|
||||||
@@ -55,10 +73,15 @@ def requires_twisted(func):
|
|||||||
|
|
||||||
def skip_with_libevent(func):
|
def skip_with_libevent(func):
|
||||||
""" Decorator that skips a test if we're using the libevent hub."""
|
""" Decorator that skips a test if we're using the libevent hub."""
|
||||||
def requirement(_f):
|
def using_libevent(_f):
|
||||||
from eventlet.api import get_hub
|
from eventlet.api import get_hub
|
||||||
return not('libevent' in type(get_hub()).__module__)
|
return 'libevent' in type(get_hub()).__module__
|
||||||
return skip_unless(requirement)(func)
|
return skip_if(using_libevent)(func)
|
||||||
|
|
||||||
|
|
||||||
|
def skip_on_windows(func):
|
||||||
|
import sys
|
||||||
|
return skip_if(sys.platform.startswith('win'))(func)
|
||||||
|
|
||||||
|
|
||||||
class TestIsTakingTooLong(Exception):
|
class TestIsTakingTooLong(Exception):
|
||||||
@@ -82,6 +105,20 @@ class LimitedTestCase(unittest.TestCase):
|
|||||||
self.timer.cancel()
|
self.timer.cancel()
|
||||||
|
|
||||||
|
|
||||||
|
class SilencedTestCase(LimitedTestCase):
|
||||||
|
""" Subclass of LimitedTestCase that also silences the printing of timer
|
||||||
|
exceptions."""
|
||||||
|
def setUp(self):
|
||||||
|
from eventlet import api
|
||||||
|
super(SilencedTestCase, self).setUp()
|
||||||
|
api.get_hub().silent_timer_exceptions = True
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
from eventlet import api
|
||||||
|
super(SilencedTestCase, self).tearDown()
|
||||||
|
api.get_hub().silent_timer_exceptions = False
|
||||||
|
|
||||||
|
|
||||||
def find_command(command):
|
def find_command(command):
|
||||||
for dir in os.getenv('PATH', '/usr/bin:/usr/sbin').split(os.pathsep):
|
for dir in os.getenv('PATH', '/usr/bin:/usr/sbin').split(os.pathsep):
|
||||||
p = os.path.join(dir, command)
|
p = os.path.join(dir, command)
|
||||||
|
@@ -1,15 +1,8 @@
|
|||||||
from unittest import TestCase, main
|
from unittest import main, TestCase
|
||||||
|
from tests import SilencedTestCase
|
||||||
from eventlet import coros, api
|
from eventlet import coros, api
|
||||||
|
|
||||||
class TestEvent(TestCase):
|
class TestEvent(SilencedTestCase):
|
||||||
mode = 'static'
|
|
||||||
def setUp(self):
|
|
||||||
# raise an exception if we're waiting forever
|
|
||||||
self._cancel_timeout = api.exc_after(1, RuntimeError('test takes too long'))
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self._cancel_timeout.cancel()
|
|
||||||
|
|
||||||
def test_waiting_for_event(self):
|
def test_waiting_for_event(self):
|
||||||
evt = coros.event()
|
evt = coros.event()
|
||||||
value = 'some stuff'
|
value = 'some stuff'
|
||||||
@@ -81,15 +74,14 @@ class IncrActor(coros.Actor):
|
|||||||
if evt: evt.send()
|
if evt: evt.send()
|
||||||
|
|
||||||
|
|
||||||
class TestActor(TestCase):
|
class TestActor(SilencedTestCase):
|
||||||
mode = 'static'
|
mode = 'static'
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# raise an exception if we're waiting forever
|
super(TestActor, self).setUp()
|
||||||
self._cancel_timeout = api.exc_after(1, api.TimeoutError())
|
|
||||||
self.actor = IncrActor()
|
self.actor = IncrActor()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self._cancel_timeout.cancel()
|
super(TestActor, self).tearDown()
|
||||||
api.kill(self.actor._killer)
|
api.kill(self.actor._killer)
|
||||||
|
|
||||||
def test_cast(self):
|
def test_cast(self):
|
||||||
|
@@ -2,6 +2,7 @@ from tests import skipped, LimitedTestCase, skip_with_libevent, TestIsTakingTooL
|
|||||||
from unittest import main
|
from unittest import main
|
||||||
from eventlet import api, util, coros, proc, greenio
|
from eventlet import api, util, coros, proc, greenio
|
||||||
from eventlet.green.socket import GreenSSLObject
|
from eventlet.green.socket import GreenSSLObject
|
||||||
|
import errno
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
@@ -29,6 +30,17 @@ def min_buf_size():
|
|||||||
return test_sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
|
return test_sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
|
||||||
|
|
||||||
class TestGreenIo(LimitedTestCase):
|
class TestGreenIo(LimitedTestCase):
|
||||||
|
def test_connect_timeout(self):
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.settimeout(0.1)
|
||||||
|
gs = greenio.GreenSocket(s)
|
||||||
|
try:
|
||||||
|
self.assertRaises(socket.timeout, gs.connect, ('192.0.2.1', 80))
|
||||||
|
except socket.error, e:
|
||||||
|
# unreachable is also a valid outcome
|
||||||
|
if e[0] != errno.EHOSTUNREACH:
|
||||||
|
raise
|
||||||
|
|
||||||
def test_close_with_makefile(self):
|
def test_close_with_makefile(self):
|
||||||
def accept_close_early(listener):
|
def accept_close_early(listener):
|
||||||
# verify that the makefile and the socket are truly independent
|
# verify that the makefile and the socket are truly independent
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
import sys
|
import sys
|
||||||
from unittest import TestCase, main
|
from tests import LimitedTestCase, main, skip_on_windows
|
||||||
|
|
||||||
from eventlet import processes, api
|
from eventlet import processes, api
|
||||||
|
|
||||||
class TestEchoPool(TestCase):
|
class TestEchoPool(LimitedTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
super(TestEchoPool, self).setUp()
|
||||||
self.pool = processes.ProcessPool('echo', ["hello"])
|
self.pool = processes.ProcessPool('echo', ["hello"])
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_echo(self):
|
def test_echo(self):
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
@@ -17,6 +19,7 @@ class TestEchoPool(TestCase):
|
|||||||
self.pool.put(proc)
|
self.pool.put(proc)
|
||||||
self.assertEquals(result, 'hello\n')
|
self.assertEquals(result, 'hello\n')
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_read_eof(self):
|
def test_read_eof(self):
|
||||||
proc = self.pool.get()
|
proc = self.pool.get()
|
||||||
try:
|
try:
|
||||||
@@ -25,17 +28,20 @@ class TestEchoPool(TestCase):
|
|||||||
finally:
|
finally:
|
||||||
self.pool.put(proc)
|
self.pool.put(proc)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_empty_echo(self):
|
def test_empty_echo(self):
|
||||||
p = processes.Process('echo', ['-n'])
|
p = processes.Process('echo', ['-n'])
|
||||||
self.assertEquals('', p.read())
|
self.assertEquals('', p.read())
|
||||||
self.assertRaises(processes.DeadProcess, p.read)
|
self.assertRaises(processes.DeadProcess, p.read)
|
||||||
|
|
||||||
|
|
||||||
class TestCatPool(TestCase):
|
class TestCatPool(LimitedTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
super(TestCatPool, self).setUp()
|
||||||
api.sleep(0)
|
api.sleep(0)
|
||||||
self.pool = processes.ProcessPool('cat')
|
self.pool = processes.ProcessPool('cat')
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_cat(self):
|
def test_cat(self):
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
@@ -49,6 +55,7 @@ class TestCatPool(TestCase):
|
|||||||
|
|
||||||
self.assertEquals(result, 'goodbye')
|
self.assertEquals(result, 'goodbye')
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_write_to_dead(self):
|
def test_write_to_dead(self):
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
@@ -61,6 +68,7 @@ class TestCatPool(TestCase):
|
|||||||
finally:
|
finally:
|
||||||
self.pool.put(proc)
|
self.pool.put(proc)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_close(self):
|
def test_close(self):
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
@@ -73,10 +81,12 @@ class TestCatPool(TestCase):
|
|||||||
self.pool.put(proc)
|
self.pool.put(proc)
|
||||||
|
|
||||||
|
|
||||||
class TestDyingProcessesLeavePool(TestCase):
|
class TestDyingProcessesLeavePool(LimitedTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
super(TestDyingProcessesLeavePool, self).setUp()
|
||||||
self.pool = processes.ProcessPool('echo', ['hello'], max_size=1)
|
self.pool = processes.ProcessPool('echo', ['hello'], max_size=1)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_dead_process_not_inserted_into_pool(self):
|
def test_dead_process_not_inserted_into_pool(self):
|
||||||
proc = self.pool.get()
|
proc = self.pool.get()
|
||||||
try:
|
try:
|
||||||
|
@@ -5,7 +5,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import unittest
|
from tests import LimitedTestCase, main, skip_on_windows
|
||||||
import re
|
import re
|
||||||
import StringIO
|
import StringIO
|
||||||
|
|
||||||
@@ -31,12 +31,14 @@ class CoroutineCallingClass(object):
|
|||||||
return self._my_dict
|
return self._my_dict
|
||||||
|
|
||||||
|
|
||||||
class TestSaranwrap(unittest.TestCase):
|
class TestSaranwrap(LimitedTestCase):
|
||||||
|
TEST_TIMEOUT=3
|
||||||
def assert_server_exists(self, prox):
|
def assert_server_exists(self, prox):
|
||||||
self.assert_(saranwrap.status(prox))
|
self.assert_(saranwrap.status(prox))
|
||||||
prox.foo = 0
|
prox.foo = 0
|
||||||
self.assertEqual(0, prox.foo)
|
self.assertEqual(0, prox.foo)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_tuple(self):
|
def test_wrap_tuple(self):
|
||||||
my_tuple = (1, 2)
|
my_tuple = (1, 2)
|
||||||
prox = saranwrap.wrap(my_tuple)
|
prox = saranwrap.wrap(my_tuple)
|
||||||
@@ -44,6 +46,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
self.assertEqual(prox[1], 2)
|
self.assertEqual(prox[1], 2)
|
||||||
self.assertEqual(len(my_tuple), 2)
|
self.assertEqual(len(my_tuple), 2)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_string(self):
|
def test_wrap_string(self):
|
||||||
my_object = "whatever"
|
my_object = "whatever"
|
||||||
prox = saranwrap.wrap(my_object)
|
prox = saranwrap.wrap(my_object)
|
||||||
@@ -51,6 +54,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
self.assertEqual(len(my_object), len(prox))
|
self.assertEqual(len(my_object), len(prox))
|
||||||
self.assertEqual(my_object.join(['a', 'b']), prox.join(['a', 'b']))
|
self.assertEqual(my_object.join(['a', 'b']), prox.join(['a', 'b']))
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_uniterable(self):
|
def test_wrap_uniterable(self):
|
||||||
# here we're treating the exception as just a normal class
|
# here we're treating the exception as just a normal class
|
||||||
prox = saranwrap.wrap(FloatingPointError())
|
prox = saranwrap.wrap(FloatingPointError())
|
||||||
@@ -62,6 +66,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
self.assertRaises(IndexError, index)
|
self.assertRaises(IndexError, index)
|
||||||
self.assertRaises(TypeError, key)
|
self.assertRaises(TypeError, key)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_dict(self):
|
def test_wrap_dict(self):
|
||||||
my_object = {'a':1}
|
my_object = {'a':1}
|
||||||
prox = saranwrap.wrap(my_object)
|
prox = saranwrap.wrap(my_object)
|
||||||
@@ -71,6 +76,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
self.assertEqual('saran:' + repr(my_object), repr(prox))
|
self.assertEqual('saran:' + repr(my_object), repr(prox))
|
||||||
self.assertEqual('saran:' + `my_object`, `prox`)
|
self.assertEqual('saran:' + `my_object`, `prox`)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_module_class(self):
|
def test_wrap_module_class(self):
|
||||||
prox = saranwrap.wrap(re)
|
prox = saranwrap.wrap(re)
|
||||||
self.assertEqual(saranwrap.Proxy, type(prox))
|
self.assertEqual(saranwrap.Proxy, type(prox))
|
||||||
@@ -78,6 +84,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
self.assertEqual(exp.flags, 0)
|
self.assertEqual(exp.flags, 0)
|
||||||
self.assert_(repr(prox.compile))
|
self.assert_(repr(prox.compile))
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_eq(self):
|
def test_wrap_eq(self):
|
||||||
prox = saranwrap.wrap(re)
|
prox = saranwrap.wrap(re)
|
||||||
exp1 = prox.compile('.')
|
exp1 = prox.compile('.')
|
||||||
@@ -86,6 +93,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
exp3 = prox.compile('/')
|
exp3 = prox.compile('/')
|
||||||
self.assert_(exp1 != exp3)
|
self.assert_(exp1 != exp3)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_nonzero(self):
|
def test_wrap_nonzero(self):
|
||||||
prox = saranwrap.wrap(re)
|
prox = saranwrap.wrap(re)
|
||||||
exp1 = prox.compile('.')
|
exp1 = prox.compile('.')
|
||||||
@@ -93,6 +101,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
prox2 = saranwrap.Proxy([1, 2, 3])
|
prox2 = saranwrap.Proxy([1, 2, 3])
|
||||||
self.assert_(bool(prox2))
|
self.assert_(bool(prox2))
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_multiple_wraps(self):
|
def test_multiple_wraps(self):
|
||||||
prox1 = saranwrap.wrap(re)
|
prox1 = saranwrap.wrap(re)
|
||||||
prox2 = saranwrap.wrap(re)
|
prox2 = saranwrap.wrap(re)
|
||||||
@@ -101,6 +110,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
del x2
|
del x2
|
||||||
x3 = prox2.compile('.')
|
x3 = prox2.compile('.')
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_dict_passthru(self):
|
def test_dict_passthru(self):
|
||||||
prox = saranwrap.wrap(StringIO)
|
prox = saranwrap.wrap(StringIO)
|
||||||
x = prox.StringIO('a')
|
x = prox.StringIO('a')
|
||||||
@@ -108,25 +118,30 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
# try it all on one line just for the sake of it
|
# try it all on one line just for the sake of it
|
||||||
self.assertEqual(type(saranwrap.wrap(StringIO).StringIO('a').__dict__), saranwrap.ObjectProxy)
|
self.assertEqual(type(saranwrap.wrap(StringIO).StringIO('a').__dict__), saranwrap.ObjectProxy)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_is_value(self):
|
def test_is_value(self):
|
||||||
server = saranwrap.Server(None, None, None)
|
server = saranwrap.Server(None, None, None)
|
||||||
self.assert_(server.is_value(None))
|
self.assert_(server.is_value(None))
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_getitem(self):
|
def test_wrap_getitem(self):
|
||||||
prox = saranwrap.wrap([0,1,2])
|
prox = saranwrap.wrap([0,1,2])
|
||||||
self.assertEqual(prox[0], 0)
|
self.assertEqual(prox[0], 0)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_wrap_setitem(self):
|
def test_wrap_setitem(self):
|
||||||
prox = saranwrap.wrap([0,1,2])
|
prox = saranwrap.wrap([0,1,2])
|
||||||
prox[1] = 2
|
prox[1] = 2
|
||||||
self.assertEqual(prox[1], 2)
|
self.assertEqual(prox[1], 2)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_raising_exceptions(self):
|
def test_raising_exceptions(self):
|
||||||
prox = saranwrap.wrap(re)
|
prox = saranwrap.wrap(re)
|
||||||
def nofunc():
|
def nofunc():
|
||||||
prox.never_name_a_function_like_this()
|
prox.never_name_a_function_like_this()
|
||||||
self.assertRaises(AttributeError, nofunc)
|
self.assertRaises(AttributeError, nofunc)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_unpicklable_server_exception(self):
|
def test_unpicklable_server_exception(self):
|
||||||
prox = saranwrap.wrap(saranwrap)
|
prox = saranwrap.wrap(saranwrap)
|
||||||
def unpickle():
|
def unpickle():
|
||||||
@@ -137,6 +152,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
# It's basically dead
|
# It's basically dead
|
||||||
#self.assert_server_exists(prox)
|
#self.assert_server_exists(prox)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_pickleable_server_exception(self):
|
def test_pickleable_server_exception(self):
|
||||||
prox = saranwrap.wrap(saranwrap)
|
prox = saranwrap.wrap(saranwrap)
|
||||||
def fperror():
|
def fperror():
|
||||||
@@ -145,11 +161,13 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
self.assertRaises(FloatingPointError, fperror)
|
self.assertRaises(FloatingPointError, fperror)
|
||||||
self.assert_server_exists(prox)
|
self.assert_server_exists(prox)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_print_does_not_break_wrapper(self):
|
def test_print_does_not_break_wrapper(self):
|
||||||
prox = saranwrap.wrap(saranwrap)
|
prox = saranwrap.wrap(saranwrap)
|
||||||
prox.print_string('hello')
|
prox.print_string('hello')
|
||||||
self.assert_server_exists(prox)
|
self.assert_server_exists(prox)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_stderr_does_not_break_wrapper(self):
|
def test_stderr_does_not_break_wrapper(self):
|
||||||
prox = saranwrap.wrap(saranwrap)
|
prox = saranwrap.wrap(saranwrap)
|
||||||
prox.err_string('goodbye')
|
prox.err_string('goodbye')
|
||||||
@@ -158,6 +176,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
def assertLessThan(self, a, b):
|
def assertLessThan(self, a, b):
|
||||||
self.assert_(a < b, "%s is not less than %s" % (a, b))
|
self.assert_(a < b, "%s is not less than %s" % (a, b))
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_status(self):
|
def test_status(self):
|
||||||
prox = saranwrap.wrap(time)
|
prox = saranwrap.wrap(time)
|
||||||
a = prox.gmtime(0)
|
a = prox.gmtime(0)
|
||||||
@@ -176,6 +195,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
prox2 = saranwrap.wrap(re)
|
prox2 = saranwrap.wrap(re)
|
||||||
self.assert_(status['pid'] != saranwrap.status(prox2)['pid'])
|
self.assert_(status['pid'] != saranwrap.status(prox2)['pid'])
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_del(self):
|
def test_del(self):
|
||||||
prox = saranwrap.wrap(time)
|
prox = saranwrap.wrap(time)
|
||||||
delme = prox.gmtime(0)
|
delme = prox.gmtime(0)
|
||||||
@@ -189,11 +209,13 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
#print status_after['objects']
|
#print status_after['objects']
|
||||||
self.assertLessThan(status_after['object_count'], status_before['object_count'])
|
self.assertLessThan(status_after['object_count'], status_before['object_count'])
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_contains(self):
|
def test_contains(self):
|
||||||
prox = saranwrap.wrap({'a':'b'})
|
prox = saranwrap.wrap({'a':'b'})
|
||||||
self.assert_('a' in prox)
|
self.assert_('a' in prox)
|
||||||
self.assert_('x' not in prox)
|
self.assert_('x' not in prox)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_variable_and_keyword_arguments_with_function_calls(self):
|
def test_variable_and_keyword_arguments_with_function_calls(self):
|
||||||
import optparse
|
import optparse
|
||||||
prox = saranwrap.wrap(optparse)
|
prox = saranwrap.wrap(optparse)
|
||||||
@@ -202,6 +224,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
opts,args = parser.parse_args(["-nfoo"])
|
opts,args = parser.parse_args(["-nfoo"])
|
||||||
self.assertEqual(opts.n, 'foo')
|
self.assertEqual(opts.n, 'foo')
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_original_proxy_going_out_of_scope(self):
|
def test_original_proxy_going_out_of_scope(self):
|
||||||
def make_re():
|
def make_re():
|
||||||
prox = saranwrap.wrap(re)
|
prox = saranwrap.wrap(re)
|
||||||
@@ -224,6 +247,7 @@ class TestSaranwrap(unittest.TestCase):
|
|||||||
except AttributeError, e:
|
except AttributeError, e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_not_inheriting_pythonpath(self):
|
def test_not_inheriting_pythonpath(self):
|
||||||
# construct a fake module in the temp directory
|
# construct a fake module in the temp directory
|
||||||
temp_dir = tempfile.mkdtemp("saranwrap_test")
|
temp_dir = tempfile.mkdtemp("saranwrap_test")
|
||||||
@@ -253,6 +277,7 @@ sys_path = sys.path""")
|
|||||||
shutil.rmtree(temp_dir)
|
shutil.rmtree(temp_dir)
|
||||||
sys.path.remove(temp_dir)
|
sys.path.remove(temp_dir)
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_contention(self):
|
def test_contention(self):
|
||||||
from tests import saranwrap_test
|
from tests import saranwrap_test
|
||||||
prox = saranwrap.wrap(saranwrap_test)
|
prox = saranwrap.wrap(saranwrap_test)
|
||||||
@@ -265,6 +290,7 @@ sys_path = sys.path""")
|
|||||||
for waiter in waiters:
|
for waiter in waiters:
|
||||||
waiter.wait()
|
waiter.wait()
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_copy(self):
|
def test_copy(self):
|
||||||
import copy
|
import copy
|
||||||
compound_object = {'a':[1,2,3]}
|
compound_object = {'a':[1,2,3]}
|
||||||
@@ -278,12 +304,14 @@ sys_path = sys.path""")
|
|||||||
make_assertions(copy.copy(prox))
|
make_assertions(copy.copy(prox))
|
||||||
make_assertions(copy.deepcopy(prox))
|
make_assertions(copy.deepcopy(prox))
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_list_of_functions(self):
|
def test_list_of_functions(self):
|
||||||
return # this test is known to fail, we can implement it sometime in the future if we wish
|
return # this test is known to fail, we can implement it sometime in the future if we wish
|
||||||
from tests import saranwrap_test
|
from tests import saranwrap_test
|
||||||
prox = saranwrap.wrap([saranwrap_test.list_maker])
|
prox = saranwrap.wrap([saranwrap_test.list_maker])
|
||||||
self.assertEquals(list_maker(), prox[0]())
|
self.assertEquals(list_maker(), prox[0]())
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_under_the_hood_coroutines(self):
|
def test_under_the_hood_coroutines(self):
|
||||||
# so, we want to write a class which uses a coroutine to call
|
# so, we want to write a class which uses a coroutine to call
|
||||||
# a function. Then we want to saranwrap that class, have
|
# a function. Then we want to saranwrap that class, have
|
||||||
@@ -302,6 +330,7 @@ sys_path = sys.path""")
|
|||||||
'random' in obj_proxy.get_dict(),
|
'random' in obj_proxy.get_dict(),
|
||||||
'Coroutine in saranwrapped object did not run')
|
'Coroutine in saranwrapped object did not run')
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_child_process_death(self):
|
def test_child_process_death(self):
|
||||||
prox = saranwrap.wrap({})
|
prox = saranwrap.wrap({})
|
||||||
pid = saranwrap.getpid(prox)
|
pid = saranwrap.getpid(prox)
|
||||||
@@ -310,17 +339,20 @@ sys_path = sys.path""")
|
|||||||
api.sleep(0.1) # need to let the signal handler run
|
api.sleep(0.1) # need to let the signal handler run
|
||||||
self.assertRaises(OSError, os.kill, pid, 0) # raises OSError if pid doesn't exist
|
self.assertRaises(OSError, os.kill, pid, 0) # raises OSError if pid doesn't exist
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_detection_of_server_crash(self):
|
def test_detection_of_server_crash(self):
|
||||||
# make the server crash here
|
# make the server crash here
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_equality_with_local_object(self):
|
def test_equality_with_local_object(self):
|
||||||
# we'll implement this if there's a use case for it
|
# we'll implement this if there's a use case for it
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@skip_on_windows
|
||||||
def test_non_blocking(self):
|
def test_non_blocking(self):
|
||||||
# here we test whether it's nonblocking
|
# here we test whether it's nonblocking
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
main()
|
||||||
|
@@ -41,6 +41,21 @@ class SSLTest(LimitedTestCase):
|
|||||||
client.close()
|
client.close()
|
||||||
server_coro.wait()
|
server_coro.wait()
|
||||||
|
|
||||||
|
def test_ssl_connect(self):
|
||||||
|
def serve(listener):
|
||||||
|
sock, addr = listener.accept()
|
||||||
|
stuff = sock.read(8192)
|
||||||
|
sock = api.ssl_listener(('127.0.0.1', 0), certificate_file, private_key_file)
|
||||||
|
server_coro = coros.execute(serve, sock)
|
||||||
|
|
||||||
|
raw_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
ssl_client = util.wrap_ssl(raw_client)
|
||||||
|
ssl_client.connect(('127.0.0.1', sock.getsockname()[1]))
|
||||||
|
ssl_client.write('abc')
|
||||||
|
greenio.shutdown_safe(ssl_client)
|
||||||
|
ssl_client.close()
|
||||||
|
server_coro.wait()
|
||||||
|
|
||||||
|
|
||||||
class SocketSSLTest(LimitedTestCase):
|
class SocketSSLTest(LimitedTestCase):
|
||||||
@skip_unless(hasattr(socket, 'ssl'))
|
@skip_unless(hasattr(socket, 'ssl'))
|
||||||
|
@@ -30,9 +30,9 @@ patcher.inject('test.test_ssl',
|
|||||||
('threading', threading),
|
('threading', threading),
|
||||||
('urllib', urllib))
|
('urllib', urllib))
|
||||||
|
|
||||||
# these appear to not work due to some wonkiness in the threading
|
# these don't pass because nonblocking ssl sockets don't report
|
||||||
# module... skipping them for now (can't use SkipTest either because
|
# when the socket is closed uncleanly, per the docstring on
|
||||||
# test_main doesn't understand it)
|
# eventlet.green.GreenSSLSocket
|
||||||
# *TODO: fix and restore these tests
|
# *TODO: fix and restore these tests
|
||||||
ThreadedTests.testProtocolSSL2 = lambda s: None
|
ThreadedTests.testProtocolSSL2 = lambda s: None
|
||||||
ThreadedTests.testProtocolSSL3 = lambda s: None
|
ThreadedTests.testProtocolSSL3 = lambda s: None
|
||||||
|
@@ -22,6 +22,7 @@ class TestEvent(LimitedTestCase):
|
|||||||
obj = Exception()
|
obj = Exception()
|
||||||
e.send(exc=obj)
|
e.send(exc=obj)
|
||||||
sleep(0)
|
sleep(0)
|
||||||
|
sleep(0)
|
||||||
assert log == [('catched', obj)], log
|
assert log == [('catched', obj)], log
|
||||||
|
|
||||||
def test_send(self):
|
def test_send(self):
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
from tests import SilencedTestCase
|
||||||
import time
|
import time
|
||||||
from eventlet import api
|
from eventlet import api
|
||||||
from eventlet.green import socket
|
from eventlet.green import socket
|
||||||
@@ -29,7 +30,7 @@ class TestDebug(unittest.TestCase):
|
|||||||
self.assert_(not api.get_hub().debug)
|
self.assert_(not api.get_hub().debug)
|
||||||
|
|
||||||
|
|
||||||
class TestExceptionInMainloop(unittest.TestCase):
|
class TestExceptionInMainloop(SilencedTestCase):
|
||||||
|
|
||||||
def test_sleep(self):
|
def test_sleep(self):
|
||||||
# even if there was an error in the mainloop, the hub should continue to work
|
# even if there was an error in the mainloop, the hub should continue to work
|
||||||
|
@@ -2,14 +2,14 @@ import sys
|
|||||||
import unittest
|
import unittest
|
||||||
from eventlet.api import sleep, with_timeout
|
from eventlet.api import sleep, with_timeout
|
||||||
from eventlet import api, proc, coros
|
from eventlet import api, proc, coros
|
||||||
from tests import LimitedTestCase, skipped
|
from tests import SilencedTestCase, skipped
|
||||||
|
|
||||||
DELAY = 0.01
|
DELAY = 0.01
|
||||||
|
|
||||||
class ExpectedError(Exception):
|
class ExpectedError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class TestLink_Signal(LimitedTestCase):
|
class TestLink_Signal(SilencedTestCase):
|
||||||
|
|
||||||
def test_send(self):
|
def test_send(self):
|
||||||
s = proc.Source()
|
s = proc.Source()
|
||||||
@@ -48,7 +48,7 @@ class TestLink_Signal(LimitedTestCase):
|
|||||||
self.assertRaises(OSError, s.wait)
|
self.assertRaises(OSError, s.wait)
|
||||||
|
|
||||||
|
|
||||||
class TestProc(LimitedTestCase):
|
class TestProc(SilencedTestCase):
|
||||||
|
|
||||||
def test_proc(self):
|
def test_proc(self):
|
||||||
p = proc.spawn(lambda : 100)
|
p = proc.spawn(lambda : 100)
|
||||||
@@ -76,13 +76,13 @@ class TestProc(LimitedTestCase):
|
|||||||
self.assertRaises(proc.LinkedCompleted, sleep, 0.1)
|
self.assertRaises(proc.LinkedCompleted, sleep, 0.1)
|
||||||
|
|
||||||
|
|
||||||
class TestCase(LimitedTestCase):
|
class TestCase(SilencedTestCase):
|
||||||
|
|
||||||
def link(self, p, listener=None):
|
def link(self, p, listener=None):
|
||||||
getattr(p, self.link_method)(listener)
|
getattr(p, self.link_method)(listener)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
LimitedTestCase.tearDown(self)
|
SilencedTestCase.tearDown(self)
|
||||||
self.p.unlink()
|
self.p.unlink()
|
||||||
|
|
||||||
def set_links(self, p, first_time, kill_exc_type):
|
def set_links(self, p, first_time, kill_exc_type):
|
||||||
@@ -252,7 +252,7 @@ class TestRaise_link_exception(TestRaise_link):
|
|||||||
link_method = 'link_exception'
|
link_method = 'link_exception'
|
||||||
|
|
||||||
|
|
||||||
class TestStuff(unittest.TestCase):
|
class TestStuff(SilencedTestCase):
|
||||||
|
|
||||||
def test_wait_noerrors(self):
|
def test_wait_noerrors(self):
|
||||||
x = proc.spawn(lambda : 1)
|
x = proc.spawn(lambda : 1)
|
||||||
@@ -297,6 +297,7 @@ class TestStuff(unittest.TestCase):
|
|||||||
proc.waitall([a, b])
|
proc.waitall([a, b])
|
||||||
except ExpectedError, ex:
|
except ExpectedError, ex:
|
||||||
assert 'second' in str(ex), repr(str(ex))
|
assert 'second' in str(ex), repr(str(ex))
|
||||||
|
api.sleep(0.2) # sleep to ensure that the other timer is raised
|
||||||
|
|
||||||
def test_multiple_listeners_error(self):
|
def test_multiple_listeners_error(self):
|
||||||
# if there was an error while calling a callback
|
# if there was an error while calling a callback
|
||||||
|
@@ -9,12 +9,20 @@ else:
|
|||||||
class TestSocketErrors(unittest.TestCase):
|
class TestSocketErrors(unittest.TestCase):
|
||||||
|
|
||||||
def test_connection_refused(self):
|
def test_connection_refused(self):
|
||||||
|
# open and close a dummy server to find an unused port
|
||||||
|
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
server.bind(('127.0.0.1', 0))
|
||||||
|
server.listen(1)
|
||||||
|
port = server.getsockname()[1]
|
||||||
|
server.close()
|
||||||
|
del server
|
||||||
s = socket.socket()
|
s = socket.socket()
|
||||||
try:
|
try:
|
||||||
s.connect(('127.0.0.1', 81))
|
s.connect(('127.0.0.1', port))
|
||||||
|
self.fail("Shouldn't have connected")
|
||||||
except socket.error, ex:
|
except socket.error, ex:
|
||||||
code, text = ex.args
|
code, text = ex.args
|
||||||
assert code in [111, 61], (code, text)
|
assert code in [111, 61, 10061], (code, text)
|
||||||
assert 'refused' in text.lower(), (code, text)
|
assert 'refused' in text.lower(), (code, text)
|
||||||
|
|
||||||
if __name__=='__main__':
|
if __name__=='__main__':
|
||||||
|
@@ -84,7 +84,12 @@ class ConnectionClosed(Exception):
|
|||||||
|
|
||||||
def read_http(sock):
|
def read_http(sock):
|
||||||
fd = sock.makeGreenFile()
|
fd = sock.makeGreenFile()
|
||||||
|
try:
|
||||||
response_line = fd.readline()
|
response_line = fd.readline()
|
||||||
|
except socket.error, exc:
|
||||||
|
if exc[0] == 10053:
|
||||||
|
raise ConnectionClosed
|
||||||
|
raise
|
||||||
if not response_line:
|
if not response_line:
|
||||||
raise ConnectionClosed
|
raise ConnectionClosed
|
||||||
raw_headers = fd.readuntil('\r\n\r\n').strip()
|
raw_headers = fd.readuntil('\r\n\r\n').strip()
|
||||||
@@ -189,6 +194,9 @@ class TestHttpd(LimitedTestCase):
|
|||||||
fd = sock.makeGreenFile()
|
fd = sock.makeGreenFile()
|
||||||
fd.write(request)
|
fd.write(request)
|
||||||
result = fd.readline()
|
result = fd.readline()
|
||||||
|
if result:
|
||||||
|
# windows closes the socket before the data is flushed,
|
||||||
|
# so we never get anything back
|
||||||
status = result.split(' ')[1]
|
status = result.split(' ')[1]
|
||||||
self.assertEqual(status, '414')
|
self.assertEqual(status, '414')
|
||||||
fd.close()
|
fd.close()
|
||||||
|
Reference in New Issue
Block a user