PEP-8 fixes, tox runs pep8 check

For now, pep8 check is only run for some files known to be clean,
we should clean the rest and enable pep8 check for all files then.
This commit is contained in:
Sergey Shepelev
2014-04-23 13:29:17 +04:00
parent 1b9f0f0edb
commit 2da62a16c3
15 changed files with 197 additions and 135 deletions

View File

@@ -122,8 +122,8 @@ class timeout(object):
Example:: Example::
with timeout(10): with timeout(10):
urllib2.open('http://example.com') urllib2.open('http://example.com')
Assuming code block is yielding (i.e. gives up control to the hub), Assuming code block is yielding (i.e. gives up control to the hub),
an exception provided in *exc* argument will be raised an exception provided in *exc* argument will be raised

View File

@@ -4,21 +4,25 @@ __all__ = __MySQLdb.__all__
__patched__ = ["connect", "Connect", 'Connection', 'connections'] __patched__ = ["connect", "Connect", 'Connection', 'connections']
from eventlet.patcher import slurp_properties from eventlet.patcher import slurp_properties
slurp_properties(__MySQLdb, globals(), slurp_properties(
__MySQLdb, globals(),
ignore=__patched__, srckeys=dir(__MySQLdb)) ignore=__patched__, srckeys=dir(__MySQLdb))
from eventlet import tpool from eventlet import tpool
__orig_connections = __import__('MySQLdb.connections').connections __orig_connections = __import__('MySQLdb.connections').connections
def Connection(*args, **kw): def Connection(*args, **kw):
conn = tpool.execute(__orig_connections.Connection, *args, **kw) conn = tpool.execute(__orig_connections.Connection, *args, **kw)
return tpool.Proxy(conn, autowrap_names=('cursor',)) return tpool.Proxy(conn, autowrap_names=('cursor',))
connect = Connect = Connection connect = Connect = Connection
# replicate the MySQLdb.connections module but with a tpooled Connection factory # replicate the MySQLdb.connections module but with a tpooled Connection factory
class MySQLdbConnectionsModule(object): class MySQLdbConnectionsModule(object):
pass pass
connections = MySQLdbConnectionsModule() connections = MySQLdbConnectionsModule()
for var in dir(__orig_connections): for var in dir(__orig_connections):
if not var.startswith('__'): if not var.startswith('__'):

View File

@@ -80,5 +80,5 @@ def emulate():
main_coro = greenlet() main_coro = greenlet()
tasklet_to_greenlet[caller] = main_coro tasklet_to_greenlet[caller] = main_coro
main_coro.t = caller main_coro.t = caller
del main_coro.switch ## It's already running del main_coro.switch # It's already running
coro_args[main_coro] = None coro_args[main_coro] = None

View File

@@ -15,21 +15,24 @@ import unittest
import warnings import warnings
import eventlet import eventlet
from eventlet import debug, hubs, tpool from eventlet import tpool
# convenience for importers # convenience for importers
main = unittest.main main = unittest.main
def s2b(s): def s2b(s):
"""portable way to convert string to bytes. In 3.x socket.send and recv require bytes""" """portable way to convert string to bytes. In 3.x socket.send and recv require bytes"""
return s.encode() return s.encode()
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."""
try: try:
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
def skipme(*a, **k): def skipme(*a, **k):
raise SkipTest() raise SkipTest()
skipme.__name__ = func.__name__ skipme.__name__ = func.__name__
@@ -107,9 +110,9 @@ def skip_with_pyevent(func):
def skip_on_windows(func): def skip_on_windows(func):
""" Decorator that skips a test on Windows.""" """ Decorator that skips a test on Windows."""
import sys
return skip_if(sys.platform.startswith('win'))(func) return skip_if(sys.platform.startswith('win'))(func)
def skip_if_no_itimer(func): def skip_if_no_itimer(func):
""" Decorator that skips a test if the `itimer` module isn't found """ """ Decorator that skips a test if the `itimer` module isn't found """
has_itimer = False has_itimer = False
@@ -186,19 +189,19 @@ class LimitedTestCase(unittest.TestCase):
eventlet.sleep(0) eventlet.sleep(0)
verify_hub_empty() verify_hub_empty()
def assert_less_than(self, a,b,msg=None): def assert_less_than(self, a, b, msg=None):
if msg: if msg:
self.assert_(a<b, msg) self.assert_(a < b, msg)
else: else:
self.assert_(a<b, "%s not less than %s" % (a,b)) self.assert_(a < b, "%s not less than %s" % (a, b))
assertLessThan = assert_less_than assertLessThan = assert_less_than
def assert_less_than_equal(self, a,b,msg=None): def assert_less_than_equal(self, a, b, msg=None):
if msg: if msg:
self.assert_(a<=b, msg) self.assert_(a <= b, msg)
else: else:
self.assert_(a<=b, "%s not less than or equal to %s" % (a,b)) self.assert_(a <= b, "%s not less than or equal to %s" % (a, b))
assertLessThanEqual = assert_less_than_equal assertLessThanEqual = assert_less_than_equal
@@ -236,6 +239,7 @@ def find_command(command):
return p return p
raise IOError(errno.ENOENT, 'Command not found: %r' % command) raise IOError(errno.ENOENT, 'Command not found: %r' % command)
def silence_warnings(func): def silence_warnings(func):
def wrapper(*args, **kw): def wrapper(*args, **kw):
warnings.simplefilter('ignore', DeprecationWarning) warnings.simplefilter('ignore', DeprecationWarning)
@@ -261,8 +265,10 @@ def get_database_auth():
connect function. connect function.
""" """
import os import os
retval = {'MySQLdb':{'host': 'localhost','user': 'root','passwd': ''}, retval = {
'psycopg2':{'user':'test'}} 'MySQLdb': {'host': 'localhost', 'user': 'root', 'passwd': ''},
'psycopg2': {'user': 'test'},
}
try: try:
import json import json
except ImportError: except ImportError:
@@ -283,9 +289,10 @@ def get_database_auth():
# Have to convert unicode objects to str objects because # Have to convert unicode objects to str objects because
# mysqldb is dum. Using a doubly-nested list comprehension # mysqldb is dum. Using a doubly-nested list comprehension
# because we know that the structure is a two-level dict. # because we know that the structure is a two-level dict.
return dict([(str(modname), dict([(str(k), str(v)) return dict(
for k, v in connectargs.items()])) [(str(modname), dict(
for modname, connectargs in auth_utf8.items()]) [(str(k), str(v)) for k, v in connectargs.items()]))
for modname, connectargs in auth_utf8.items()])
except IOError: except IOError:
pass pass
return retval return retval

View File

@@ -1,10 +1,10 @@
import sys import sys
from unittest import TestCase
import eventlet
from eventlet import debug from eventlet import debug
from eventlet.support import six from eventlet.support import six
from tests import LimitedTestCase, main, s2b from tests import LimitedTestCase, main, s2b
from unittest import TestCase import eventlet
class TestSpew(TestCase): class TestSpew(TestCase):
@@ -34,7 +34,7 @@ class TestSpew(TestCase):
s = debug.Spew() s = debug.Spew()
f = sys._getframe() f = sys._getframe()
s(f, "line", None) s(f, "line", None)
lineno = f.f_lineno - 1 # -1 here since we called with frame f in the line above lineno = f.f_lineno - 1 # -1 here since we called with frame f in the line above
output = sys.stdout.getvalue() output = sys.stdout.getvalue()
self.failUnless("%s:%i" % (__name__, lineno) in output, "Didn't find line %i in %s" % (lineno, output)) self.failUnless("%s:%i" % (__name__, lineno) in output, "Didn't find line %i in %s" % (lineno, output))
self.failUnless("f=<frame object at" in output) self.failUnless("f=<frame object at" in output)
@@ -57,7 +57,7 @@ class TestSpew(TestCase):
GLOBAL_VAR = debug.Spew() GLOBAL_VAR = debug.Spew()
f = sys._getframe() f = sys._getframe()
GLOBAL_VAR(f, "line", None) GLOBAL_VAR(f, "line", None)
lineno = f.f_lineno - 1 # -1 here since we called with frame f in the line above lineno = f.f_lineno - 1 # -1 here since we called with frame f in the line above
output = sys.stdout.getvalue() output = sys.stdout.getvalue()
self.failUnless("%s:%i" % (__name__, lineno) in output, "Didn't find line %i in %s" % (lineno, output)) self.failUnless("%s:%i" % (__name__, lineno) in output, "Didn't find line %i in %s" % (lineno, output))
self.failUnless("f=<frame object at" in output) self.failUnless("f=<frame object at" in output)
@@ -70,7 +70,7 @@ class TestSpew(TestCase):
s = debug.Spew(show_values=False) s = debug.Spew(show_values=False)
f = sys._getframe() f = sys._getframe()
s(f, "line", None) s(f, "line", None)
lineno = f.f_lineno - 1 # -1 here since we called with frame f in the line above lineno = f.f_lineno - 1 # -1 here since we called with frame f in the line above
output = sys.stdout.getvalue() output = sys.stdout.getvalue()
self.failUnless("%s:%i" % (__name__, lineno) in output, "Didn't find line %i in %s" % (lineno, output)) self.failUnless("%s:%i" % (__name__, lineno) in output, "Didn't find line %i in %s" % (lineno, output))
self.failIf("f=<frame object at" in output) self.failIf("f=<frame object at" in output)
@@ -80,7 +80,6 @@ class TestSpew(TestCase):
s = debug.Spew(trace_names=['foo']) s = debug.Spew(trace_names=['foo'])
f = sys._getframe() f = sys._getframe()
s(f, "line", None) s(f, "line", None)
lineno = f.f_lineno - 1 # -1 here since we called with frame f in the line above
output = sys.stdout.getvalue() output = sys.stdout.getvalue()
self.failUnlessEqual(output, "") self.failUnlessEqual(output, "")

View File

@@ -2,6 +2,7 @@ import os
from tests.patcher_test import ProcessBase from tests.patcher_test import ProcessBase
from tests import skip_with_pyevent from tests import skip_with_pyevent
class Socket(ProcessBase): class Socket(ProcessBase):
def test_patched_thread(self): def test_patched_thread(self):
new_mod = """from eventlet.green import socket new_mod = """from eventlet.green import socket
@@ -16,6 +17,7 @@ socket.getaddrinfo('localhost', 80)
finally: finally:
del os.environ['EVENTLET_TPOOL_DNS'] del os.environ['EVENTLET_TPOOL_DNS']
class Tpool(ProcessBase): class Tpool(ProcessBase):
@skip_with_pyevent @skip_with_pyevent
def test_tpool_size(self): def test_tpool_size(self):

View File

@@ -2,9 +2,9 @@ from __future__ import with_statement
import os import os
from eventlet import greenio
from tests import LimitedTestCase from tests import LimitedTestCase
from eventlet import greenio
class TestGreenPipeWithStatement(LimitedTestCase): class TestGreenPipeWithStatement(LimitedTestCase):
def test_pipe_context(self): def test_pipe_context(self):

View File

@@ -252,7 +252,6 @@ class TestSuspend(LimitedTestCase):
TEST_TIMEOUT = 3 TEST_TIMEOUT = 3
def test_suspend_doesnt_crash(self): def test_suspend_doesnt_crash(self):
import errno
import os import os
import shutil import shutil
import signal import signal

View File

@@ -3,13 +3,14 @@ from __future__ import print_function
import os import os
import time import time
import traceback import traceback
import eventlet
from eventlet import event
from tests import ( from tests import (
LimitedTestCase, LimitedTestCase,
run_python, run_python,
skip_unless, using_pyevent, get_database_auth, skip_unless, using_pyevent, get_database_auth,
) )
import eventlet
from eventlet import event
try: try:
from eventlet.green import MySQLdb from eventlet.green import MySQLdb
except ImportError: except ImportError:
@@ -39,9 +40,9 @@ def mysql_requirement(_f):
return False return False
class MySQLdbTester(LimitedTestCase): class TestMySQLdb(LimitedTestCase):
def setUp(self): def setUp(self):
super(MySQLdbTester, self).setUp() super(TestMySQLdb, self).setUp()
self._auth = get_database_auth()['MySQLdb'] self._auth = get_database_auth()['MySQLdb']
self.create_db() self.create_db()
@@ -60,7 +61,7 @@ class MySQLdbTester(LimitedTestCase):
self.connection.close() self.connection.close()
self.drop_db() self.drop_db()
super(MySQLdbTester, self).tearDown() super(TestMySQLdb, self).tearDown()
@skip_unless(mysql_requirement) @skip_unless(mysql_requirement)
def create_db(self): def create_db(self):
@@ -113,6 +114,7 @@ class MySQLdbTester(LimitedTestCase):
def assert_cursor_yields(self, curs): def assert_cursor_yields(self, curs):
counter = [0] counter = [0]
def tick(): def tick():
while True: while True:
counter[0] += 1 counter[0] += 1
@@ -183,6 +185,7 @@ class MySQLdbTester(LimitedTestCase):
results = [] results = []
SHORT_QUERY = "select * from test_table" SHORT_QUERY = "select * from test_table"
evt = event.Event() evt = event.Event()
def a_query(): def a_query():
self.assert_cursor_works(curs) self.assert_cursor_works(curs)
curs.execute(SHORT_QUERY) curs.execute(SHORT_QUERY)

View File

@@ -35,16 +35,17 @@ assert count[0] > 100, count[0]
print("done") print("done")
""" """
class PatchingPsycopg(patcher_test.ProcessBase): class PatchingPsycopg(patcher_test.ProcessBase):
@skip_unless(postgres_requirement) @skip_unless(postgres_requirement)
def test_psycopg_patched(self): def test_psycopg_patched(self):
if 'PSYCOPG_TEST_DSN' not in os.environ: if 'PSYCOPG_TEST_DSN' not in os.environ:
# construct a non-json dsn for the subprocess # construct a non-json dsn for the subprocess
psycopg_auth = get_database_auth()['psycopg2'] psycopg_auth = get_database_auth()['psycopg2']
if isinstance(psycopg_auth,str): if isinstance(psycopg_auth, str):
dsn = psycopg_auth dsn = psycopg_auth
else: else:
dsn = " ".join(["%s=%s" % (k,v) for k,v, in psycopg_auth.iteritems()]) dsn = " ".join(["%s=%s" % (k, v) for k, v in psycopg_auth.iteritems()])
os.environ['PSYCOPG_TEST_DSN'] = dsn os.environ['PSYCOPG_TEST_DSN'] = dsn
self.write_to_tempfile("psycopg_patcher", psycopg_test_file) self.write_to_tempfile("psycopg_patcher", psycopg_test_file)
output, lines = self.launch_subprocess('psycopg_patcher.py') output, lines = self.launch_subprocess('psycopg_patcher.py')
@@ -53,4 +54,3 @@ class PatchingPsycopg(patcher_test.ProcessBase):
return return
# if there's anything wrong with the test program it'll have a stack trace # if there's anything wrong with the test program it'll have a stack trace
self.assert_(lines[0].startswith('done'), output) self.assert_(lines[0].startswith('done'), output)

View File

@@ -1,6 +1,5 @@
import os import os
import shutil import shutil
import subprocess
import sys import sys
import tempfile import tempfile
@@ -134,7 +133,6 @@ print("newmod")
self.assertEqual(len(lines), 2, repr(output)) self.assertEqual(len(lines), 2, repr(output))
self.assert_(lines[0].startswith('newmod'), repr(output)) self.assert_(lines[0].startswith('newmod'), repr(output))
def test_typeerror(self): def test_typeerror(self):
new_mod = """ new_mod = """
from eventlet import patcher from eventlet import patcher
@@ -145,7 +143,6 @@ patcher.monkey_patch(finagle=True)
self.assert_(lines[-2].startswith('TypeError'), repr(output)) self.assert_(lines[-2].startswith('TypeError'), repr(output))
self.assert_('finagle' in lines[-2], repr(output)) self.assert_('finagle' in lines[-2], repr(output))
def assert_boolean_logic(self, call, expected, not_expected=''): def assert_boolean_logic(self, call, expected, not_expected=''):
expected_list = ", ".join(['"%s"' % x for x in expected.split(',') if len(x)]) expected_list = ", ".join(['"%s"' % x for x in expected.split(',') if len(x)])
not_expected_list = ", ".join(['"%s"' % x for x in not_expected.split(',') if len(x)]) not_expected_list = ", ".join(['"%s"' % x for x in not_expected.split(',') if len(x)])
@@ -167,54 +164,52 @@ print("already_patched {0}".format(",".join(sorted(patcher.already_patched.keys(
patched_modules = patched_modules.replace("psycopg,", "") patched_modules = patched_modules.replace("psycopg,", "")
# ditto for MySQLdb # ditto for MySQLdb
patched_modules = patched_modules.replace("MySQLdb,", "") patched_modules = patched_modules.replace("MySQLdb,", "")
self.assertEqual(patched_modules, expected, self.assertEqual(
"Logic:%s\nExpected: %s != %s" %(call, expected, patched_modules, expected,
patched_modules)) "Logic:%s\nExpected: %s != %s" % (call, expected, patched_modules))
def test_boolean(self): def test_boolean(self):
self.assert_boolean_logic("patcher.monkey_patch()", self.assert_boolean_logic("patcher.monkey_patch()",
'os,select,socket,thread,time') 'os,select,socket,thread,time')
def test_boolean_all(self): def test_boolean_all(self):
self.assert_boolean_logic("patcher.monkey_patch(all=True)", self.assert_boolean_logic("patcher.monkey_patch(all=True)",
'os,select,socket,thread,time') 'os,select,socket,thread,time')
def test_boolean_all_single(self): def test_boolean_all_single(self):
self.assert_boolean_logic("patcher.monkey_patch(all=True, socket=True)", self.assert_boolean_logic("patcher.monkey_patch(all=True, socket=True)",
'os,select,socket,thread,time') 'os,select,socket,thread,time')
def test_boolean_all_negative(self): def test_boolean_all_negative(self):
self.assert_boolean_logic("patcher.monkey_patch(all=False, "\ self.assert_boolean_logic(
"socket=False, select=True)", "patcher.monkey_patch(all=False, socket=False, select=True)",
'select') 'select')
def test_boolean_single(self): def test_boolean_single(self):
self.assert_boolean_logic("patcher.monkey_patch(socket=True)", self.assert_boolean_logic("patcher.monkey_patch(socket=True)",
'socket') 'socket')
def test_boolean_double(self): def test_boolean_double(self):
self.assert_boolean_logic("patcher.monkey_patch(socket=True,"\ self.assert_boolean_logic("patcher.monkey_patch(socket=True, select=True)",
" select=True)", 'select,socket')
'select,socket')
def test_boolean_negative(self): def test_boolean_negative(self):
self.assert_boolean_logic("patcher.monkey_patch(socket=False)", self.assert_boolean_logic("patcher.monkey_patch(socket=False)",
'os,select,thread,time') 'os,select,thread,time')
def test_boolean_negative2(self): def test_boolean_negative2(self):
self.assert_boolean_logic("patcher.monkey_patch(socket=False,"\ self.assert_boolean_logic("patcher.monkey_patch(socket=False, time=False)",
"time=False)", 'os,select,thread')
'os,select,thread')
def test_conflicting_specifications(self): def test_conflicting_specifications(self):
self.assert_boolean_logic("patcher.monkey_patch(socket=False, "\ self.assert_boolean_logic("patcher.monkey_patch(socket=False, select=True)",
"select=True)", 'select')
'select')
test_monkey_patch_threading = """ test_monkey_patch_threading = """
def test_monkey_patch_threading(): def test_monkey_patch_threading():
tickcount = [0] tickcount = [0]
def tick(): def tick():
from eventlet.support import six from eventlet.support import six
for i in six.moves.range(1000): for i in six.moves.range(1000):
@@ -232,8 +227,9 @@ def test_monkey_patch_threading():
tpool.killall() tpool.killall()
""" """
class Tpool(ProcessBase): class Tpool(ProcessBase):
TEST_TIMEOUT=3 TEST_TIMEOUT = 3
@skip_with_pyevent @skip_with_pyevent
def test_simple(self): def test_simple(self):

View File

@@ -3,20 +3,25 @@ To do that spawn a green server and then access it using a green socket.
If either operation blocked the whole script would block and timeout. If either operation blocked the whole script would block and timeout.
""" """
import unittest import unittest
from eventlet.green import urllib2, BaseHTTPServer from eventlet.green import urllib2, BaseHTTPServer
from eventlet import spawn, kill from eventlet import spawn, kill
class QuietHandler(BaseHTTPServer.BaseHTTPRequestHandler): class QuietHandler(BaseHTTPServer.BaseHTTPRequestHandler):
protocol_version = "HTTP/1.0" protocol_version = "HTTP/1.0"
def log_message(self, *args, **kw): def log_message(self, *args, **kw):
pass pass
def start_http_server(): def start_http_server():
server_address = ('localhost', 0) server_address = ('localhost', 0)
httpd = BaseHTTPServer.HTTPServer(server_address, QuietHandler) httpd = BaseHTTPServer.HTTPServer(server_address, QuietHandler)
sa = httpd.socket.getsockname() sa = httpd.socket.getsockname()
#print("Serving HTTP on", sa[0], "port", sa[1], "...") #print("Serving HTTP on", sa[0], "port", sa[1], "...")
httpd.request_count = 0 httpd.request_count = 0
def serve(): def serve():
# increment the request_count before handling the request because # increment the request_count before handling the request because
# the send() for the response blocks (or at least appeared to be) # the send() for the response blocks (or at least appeared to be)
@@ -24,10 +29,11 @@ def start_http_server():
httpd.handle_request() httpd.handle_request()
return spawn(serve), httpd, sa[1] return spawn(serve), httpd, sa[1]
class TestGreenness(unittest.TestCase): class TestGreenness(unittest.TestCase):
def setUp(self): def setUp(self):
self.gthread, self.server,self.port = start_http_server() self.gthread, self.server, self.port = start_http_server()
#print('Spawned the server') #print('Spawned the server')
def tearDown(self): def tearDown(self):

View File

@@ -1,18 +1,19 @@
"""This test checks that socket instances (not GreenSockets but underlying sockets) """This test checks that socket instances (not GreenSockets but underlying sockets)
are not leaked by the hub. are not leaked by the hub.
""" """
import sys import gc
import unittest
from pprint import pformat from pprint import pformat
import unittest
import weakref
from eventlet.support import clear_sys_exc_info from eventlet.support import clear_sys_exc_info
from eventlet.green import socket from eventlet.green import socket
from eventlet.green.thread import start_new_thread from eventlet.green.thread import start_new_thread
from eventlet.green.time import sleep from eventlet.green.time import sleep
import weakref
import gc
SOCKET_TIMEOUT = 0.1 SOCKET_TIMEOUT = 0.1
def init_server(): def init_server():
s = socket.socket() s = socket.socket()
s.settimeout(SOCKET_TIMEOUT) s.settimeout(SOCKET_TIMEOUT)
@@ -21,6 +22,7 @@ def init_server():
s.listen(5) s.listen(5)
return s, s.getsockname()[1] return s, s.getsockname()[1]
def handle_request(s, raise_on_timeout): def handle_request(s, raise_on_timeout):
try: try:
conn, address = s.accept() conn, address = s.accept()
@@ -51,6 +53,7 @@ def make_request(port):
#print('make_request - recvd %r' % res) #print('make_request - recvd %r' % res)
#s.close() #s.close()
def run_interaction(run_client): def run_interaction(run_client):
s, port = init_server() s, port = init_server()
start_new_thread(handle_request, (s, run_client)) start_new_thread(handle_request, (s, run_client))
@@ -61,6 +64,7 @@ def run_interaction(run_client):
#s.close() #s.close()
return weakref.ref(s.fd) return weakref.ref(s.fd)
def run_and_check(run_client): def run_and_check(run_client):
w = run_interaction(run_client=run_client) w = run_interaction(run_client=run_client)
clear_sys_exc_info() clear_sys_exc_info()

View File

@@ -1,24 +1,30 @@
import cgi import cgi
import collections import collections
from eventlet import greenthread
import eventlet
import errno import errno
import os import os
import signal
import socket import socket
import sys import sys
from tests import skipped, LimitedTestCase, skip_with_pyevent, skip_if_no_ssl import traceback
from unittest import main import unittest
from eventlet import greenio import eventlet
from eventlet import debug
from eventlet import event from eventlet import event
from eventlet import hubs from eventlet import greenio
from eventlet.green import socket as greensocket from eventlet import greenthread
from eventlet import tpool
from eventlet import wsgi from eventlet import wsgi
from eventlet.green import socket as greensocket
from eventlet.green import ssl
from eventlet.green import subprocess
from eventlet.support import get_errno, six from eventlet.support import get_errno, six
from tests import find_command, run_python from tests import (
LimitedTestCase,
httplib = eventlet.import_patched('httplib') skipped, skip_with_pyevent, skip_if_no_ssl,
find_command, run_python,
)
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt') certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key') private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
@@ -307,10 +313,9 @@ class TestHttpd(_TestBase):
def test_005_run_apachebench(self): def test_005_run_apachebench(self):
url = 'http://localhost:12346/' url = 'http://localhost:12346/'
# ab is apachebench # ab is apachebench
from eventlet.green import subprocess subprocess.call(
subprocess.call([find_command('ab'), [find_command('ab'), '-c', '64', '-n', '1024', '-k', url],
'-c','64','-n','1024', '-k', url], stdout=subprocess.PIPE)
stdout=subprocess.PIPE)
def test_006_reject_long_urls(self): def test_006_reject_long_urls(self):
sock = eventlet.connect( sock = eventlet.connect(
@@ -359,8 +364,7 @@ class TestHttpd(_TestBase):
fd.close() fd.close()
def test_008_correctresponse(self): def test_008_correctresponse(self):
sock = eventlet.connect( sock = eventlet.connect(('localhost', self.port))
('localhost', self.port))
fd = sock.makefile('w') fd = sock.makefile('w')
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n') fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
@@ -368,7 +372,7 @@ class TestHttpd(_TestBase):
result_200 = read_http(sock) result_200 = read_http(sock)
fd.write('GET /notexist HTTP/1.1\r\nHost: localhost\r\n\r\n') fd.write('GET /notexist HTTP/1.1\r\nHost: localhost\r\n\r\n')
fd.flush() fd.flush()
result_404 = read_http(sock) read_http(sock)
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n') fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
fd.flush() fd.flush()
result_test = read_http(sock) result_test = read_http(sock)
@@ -416,7 +420,7 @@ class TestHttpd(_TestBase):
chunklen = int(fd.readline(), 16) chunklen = int(fd.readline(), 16)
while chunklen: while chunklen:
chunks += 1 chunks += 1
chunk = fd.read(chunklen) fd.read(chunklen)
fd.readline() # CRLF fd.readline() # CRLF
chunklen = int(fd.readline(), 16) chunklen = int(fd.readline(), 16)
self.assert_(chunks > 1) self.assert_(chunks > 1)
@@ -540,8 +544,8 @@ class TestHttpd(_TestBase):
break break
else: else:
header_lines.append(line) header_lines.append(line)
self.assertEquals(1, len([l for l in header_lines self.assertEquals(1, len(
if l.lower().startswith('content-length')])) [l for l in header_lines if l.lower().startswith('content-length')]))
@skip_if_no_ssl @skip_if_no_ssl
def test_017_ssl_zeroreturnerror(self): def test_017_ssl_zeroreturnerror(self):
@@ -553,7 +557,6 @@ class TestHttpd(_TestBase):
serv.process_request(client_socket) serv.process_request(client_socket)
return True return True
except: except:
import traceback
traceback.print_exc() traceback.print_exc()
return False return False
@@ -564,15 +567,15 @@ class TestHttpd(_TestBase):
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt') certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key') private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
sock = eventlet.wrap_ssl(eventlet.listen(('localhost', 0)), sock = eventlet.wrap_ssl(
certfile=certificate_file, eventlet.listen(('localhost', 0)),
keyfile=private_key_file, certfile=certificate_file, keyfile=private_key_file,
server_side=True) server_side=True)
server_coro = eventlet.spawn(server, sock, wsgi_app, self.logfile) server_coro = eventlet.spawn(server, sock, wsgi_app, self.logfile)
client = eventlet.connect(('localhost', sock.getsockname()[1])) client = eventlet.connect(('localhost', sock.getsockname()[1]))
client = eventlet.wrap_ssl(client) client = eventlet.wrap_ssl(client)
client.write('X') # non-empty payload so that SSL handshake occurs client.write('X') # non-empty payload so that SSL handshake occurs
greenio.shutdown_safe(client) greenio.shutdown_safe(client)
client.close() client.close()
@@ -602,9 +605,7 @@ class TestHttpd(_TestBase):
def test_019_fieldstorage_compat(self): def test_019_fieldstorage_compat(self):
def use_fieldstorage(environ, start_response): def use_fieldstorage(environ, start_response):
import cgi cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
fs = cgi.FieldStorage(fp=environ['wsgi.input'],
environ=environ)
start_response('200 OK', [('Content-type', 'text/plain')]) start_response('200 OK', [('Content-type', 'text/plain')])
return ['hello!'] return ['hello!']
@@ -623,8 +624,13 @@ class TestHttpd(_TestBase):
self.assert_('hello!' in fd.read()) self.assert_('hello!' in fd.read())
def test_020_x_forwarded_for(self): def test_020_x_forwarded_for(self):
request_bytes = (
b'GET / HTTP/1.1\r\nHost: localhost\r\n'
+ b'X-Forwarded-For: 1.2.3.4, 5.6.7.8\r\n\r\n'
)
sock = eventlet.connect(('localhost', self.port)) sock = eventlet.connect(('localhost', self.port))
sock.sendall('GET / HTTP/1.1\r\nHost: localhost\r\nX-Forwarded-For: 1.2.3.4, 5.6.7.8\r\n\r\n') sock.sendall(request_bytes)
sock.recv(1024) sock.recv(1024)
sock.close() sock.close()
self.assert_('1.2.3.4,5.6.7.8,127.0.0.1' in self.logfile.getvalue()) self.assert_('1.2.3.4,5.6.7.8,127.0.0.1' in self.logfile.getvalue())
@@ -634,7 +640,7 @@ class TestHttpd(_TestBase):
self.spawn_server(log_x_forwarded_for=False) self.spawn_server(log_x_forwarded_for=False)
sock = eventlet.connect(('localhost', self.port)) sock = eventlet.connect(('localhost', self.port))
sock.sendall('GET / HTTP/1.1\r\nHost: localhost\r\nX-Forwarded-For: 1.2.3.4, 5.6.7.8\r\n\r\n') sock.sendall(request_bytes)
sock.recv(1024) sock.recv(1024)
sock.close() sock.close()
self.assert_('1.2.3.4' not in self.logfile.getvalue()) self.assert_('1.2.3.4' not in self.logfile.getvalue())
@@ -659,7 +665,7 @@ class TestHttpd(_TestBase):
# shut down the server and verify the server_socket fd is still open, # shut down the server and verify the server_socket fd is still open,
# but the actual socketobject passed in to wsgi.server is closed # but the actual socketobject passed in to wsgi.server is closed
greenthread.kill(self.killer) greenthread.kill(self.killer)
eventlet.sleep(0) # make the kill go through eventlet.sleep(0) # make the kill go through
try: try:
server_sock_2.accept() server_sock_2.accept()
# shouldn't be able to use this one anymore # shouldn't be able to use this one anymore
@@ -677,12 +683,13 @@ class TestHttpd(_TestBase):
def test_021_environ_clobbering(self): def test_021_environ_clobbering(self):
def clobberin_time(environ, start_response): def clobberin_time(environ, start_response):
for environ_var in ['wsgi.version', 'wsgi.url_scheme', for environ_var in [
'wsgi.input', 'wsgi.errors', 'wsgi.multithread', 'wsgi.version', 'wsgi.url_scheme',
'wsgi.multiprocess', 'wsgi.run_once', 'REQUEST_METHOD', 'wsgi.input', 'wsgi.errors', 'wsgi.multithread',
'SCRIPT_NAME', 'RAW_PATH_INFO', 'PATH_INFO', 'QUERY_STRING', 'wsgi.multiprocess', 'wsgi.run_once', 'REQUEST_METHOD',
'CONTENT_TYPE', 'CONTENT_LENGTH', 'SERVER_NAME', 'SERVER_PORT', 'SCRIPT_NAME', 'RAW_PATH_INFO', 'PATH_INFO', 'QUERY_STRING',
'SERVER_PROTOCOL']: 'CONTENT_TYPE', 'CONTENT_LENGTH', 'SERVER_NAME', 'SERVER_PORT',
'SERVER_PROTOCOL']:
environ[environ_var] = None environ[environ_var] = None
start_response('200 OK', [('Content-type', 'text/plain')]) start_response('200 OK', [('Content-type', 'text/plain')])
return [] return []
@@ -700,8 +707,7 @@ class TestHttpd(_TestBase):
# just test that it accepts the parameter for now # just test that it accepts the parameter for now
# TODO: test that it uses the pool and that you can waitall() to # TODO: test that it uses the pool and that you can waitall() to
# ensure that all clients finished # ensure that all clients finished
from eventlet import greenpool p = eventlet.GreenPool(5)
p = greenpool.GreenPool(5)
self.spawn_server(custom_pool=p) self.spawn_server(custom_pool=p)
# this stuff is copied from test_001_server, could be better factored # this stuff is copied from test_001_server, could be better factored
@@ -767,7 +773,6 @@ class TestHttpd(_TestBase):
sock.close() sock.close()
def test_025_accept_errors(self): def test_025_accept_errors(self):
from eventlet import debug
debug.hub_exceptions(True) debug.hub_exceptions(True)
listener = greensocket.socket() listener = greensocket.socket()
listener.bind(('localhost', 0)) listener.bind(('localhost', 0))
@@ -777,7 +782,7 @@ class TestHttpd(_TestBase):
old_stderr = sys.stderr old_stderr = sys.stderr
try: try:
sys.stderr = self.logfile sys.stderr = self.logfile
eventlet.sleep(0) # need to enter server loop eventlet.sleep(0) # need to enter server loop
try: try:
eventlet.connect(('localhost', self.port)) eventlet.connect(('localhost', self.port))
self.fail("Didn't expect to connect") self.fail("Didn't expect to connect")
@@ -785,7 +790,7 @@ class TestHttpd(_TestBase):
self.assertEquals(get_errno(exc), errno.ECONNREFUSED) self.assertEquals(get_errno(exc), errno.ECONNREFUSED)
self.assert_('Invalid argument' in self.logfile.getvalue(), self.assert_('Invalid argument' in self.logfile.getvalue(),
self.logfile.getvalue()) self.logfile.getvalue())
finally: finally:
sys.stderr = old_stderr sys.stderr = old_stderr
debug.hub_exceptions(False) debug.hub_exceptions(False)
@@ -835,7 +840,10 @@ class TestHttpd(_TestBase):
result = read_http(sock) result = read_http(sock)
self.assertEqual(result.status, 'HTTP/1.1 200 OK') self.assertEqual(result.status, 'HTTP/1.1 200 OK')
self.assertEqual(result.headers_lower.get('transfer-encoding'), 'chunked') self.assertEqual(result.headers_lower.get('transfer-encoding'), 'chunked')
self.assertEqual(result.body, '27\r\nThe dwarves of yore made mighty spells,\r\n25\r\nWhile hammers fell like ringing bells\r\n') expected_body = (
b'27\r\nThe dwarves of yore made mighty spells,\r\n'
b'25\r\nWhile hammers fell like ringing bells\r\n')
self.assertEqual(result.body, expected_body)
# verify that socket is closed by server # verify that socket is closed by server
self.assertEqual(sock.recv(1), '') self.assertEqual(sock.recv(1), '')
@@ -855,16 +863,19 @@ class TestHttpd(_TestBase):
self.site.application = chunked_post self.site.application = chunked_post
sock = eventlet.connect(('localhost', self.port)) sock = eventlet.connect(('localhost', self.port))
fd = sock.makefile('w') fd = sock.makefile('w')
fd.write('PUT /a HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n10\r\n0123456789abcdef\r\n0\r\n\r\n') common_suffix = (
b'Host: localhost\r\nTransfer-Encoding: chunked\r\n\r\n' +
b'10\r\n0123456789abcdef\r\n0\r\n\r\n')
fd.write(b'PUT /a HTTP/1.1\r\n' + common_suffix)
fd.flush() fd.flush()
read_http(sock) read_http(sock)
fd.write('PUT /b HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n10\r\n0123456789abcdef\r\n0\r\n\r\n') fd.write(b'PUT /b HTTP/1.1\r\n' + common_suffix)
fd.flush() fd.flush()
read_http(sock) read_http(sock)
fd.write('PUT /c HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n10\r\n0123456789abcdef\r\n0\r\n\r\n') fd.write(b'PUT /c HTTP/1.1\r\n' + common_suffix)
fd.flush() fd.flush()
read_http(sock) read_http(sock)
fd.write('PUT /a HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n10\r\n0123456789abcdef\r\n0\r\n\r\n') fd.write(b'PUT /a HTTP/1.1\r\n' + common_suffix)
fd.flush() fd.flush()
read_http(sock) read_http(sock)
sock.close() sock.close()
@@ -872,6 +883,7 @@ class TestHttpd(_TestBase):
@skip_if_no_ssl @skip_if_no_ssl
def test_028_ssl_handshake_errors(self): def test_028_ssl_handshake_errors(self):
errored = [False] errored = [False]
def server(sock): def server(sock):
try: try:
wsgi.server(sock=sock, site=hello_world, log=self.logfile) wsgi.server(sock=sock, site=hello_world, log=self.logfile)
@@ -881,37 +893,38 @@ class TestHttpd(_TestBase):
except Exception as e: except Exception as e:
errored[0] = 'SSL handshake error raised exception %s.' % e errored[0] = 'SSL handshake error raised exception %s.' % e
for data in ('', 'GET /non-ssl-request HTTP/1.0\r\n\r\n'): for data in ('', 'GET /non-ssl-request HTTP/1.0\r\n\r\n'):
srv_sock = eventlet.wrap_ssl(eventlet.listen(('localhost', 0)), srv_sock = eventlet.wrap_ssl(
certfile=certificate_file, eventlet.listen(('localhost', 0)),
keyfile=private_key_file, certfile=certificate_file, keyfile=private_key_file,
server_side=True) server_side=True)
port = srv_sock.getsockname()[1] port = srv_sock.getsockname()[1]
g = eventlet.spawn_n(server, srv_sock) g = eventlet.spawn_n(server, srv_sock)
client = eventlet.connect(('localhost', port)) client = eventlet.connect(('localhost', port))
if data: # send non-ssl request if data: # send non-ssl request
client.sendall(data) client.sendall(data)
else: # close sock prematurely else: # close sock prematurely
client.close() client.close()
eventlet.sleep(0) # let context switch back to server eventlet.sleep(0) # let context switch back to server
self.assert_(not errored[0], errored[0]) self.assert_(not errored[0], errored[0])
# make another request to ensure the server's still alive # make another request to ensure the server's still alive
try: try:
from eventlet.green import ssl
client = ssl.wrap_socket(eventlet.connect(('localhost', port))) client = ssl.wrap_socket(eventlet.connect(('localhost', port)))
client.write('GET / HTTP/1.0\r\nHost: localhost\r\n\r\n') client.write('GET / HTTP/1.0\r\nHost: localhost\r\n\r\n')
result = client.read() result = client.read()
self.assert_(result.startswith('HTTP'), result) self.assert_(result.startswith('HTTP'), result)
self.assert_(result.endswith('hello world')) self.assert_(result.endswith('hello world'))
except ImportError: except ImportError:
pass # TODO: should test with OpenSSL pass # TODO: should test with OpenSSL
greenthread.kill(g) greenthread.kill(g)
def test_029_posthooks(self): def test_029_posthooks(self):
posthook1_count = [0] posthook1_count = [0]
posthook2_count = [0] posthook2_count = [0]
def posthook1(env, value, multiplier=1): def posthook1(env, value, multiplier=1):
self.assertEquals(env['local.test'], 'test_029_posthooks') self.assertEquals(env['local.test'], 'test_029_posthooks')
posthook1_count[0] += value * multiplier posthook1_count[0] += value * multiplier
def posthook2(env, value, divisor=1): def posthook2(env, value, divisor=1):
self.assertEquals(env['local.test'], 'test_029_posthooks') self.assertEquals(env['local.test'], 'test_029_posthooks')
posthook2_count[0] += value / divisor posthook2_count[0] += value / divisor
@@ -1054,6 +1067,7 @@ class TestHttpd(_TestBase):
def test_aborted_chunked_post(self): def test_aborted_chunked_post(self):
read_content = event.Event() read_content = event.Event()
blew_up = [False] blew_up = [False]
def chunk_reader(env, start_response): def chunk_reader(env, start_response):
try: try:
content = env['wsgi.input'].read(1024) content = env['wsgi.input'].read(1024)
@@ -1115,8 +1129,7 @@ class TestHttpd(_TestBase):
self.site.application = wsgi_app self.site.application = wsgi_app
sock = eventlet.connect(('localhost', self.port)) sock = eventlet.connect(('localhost', self.port))
fd = sock.makefile('rw') fd = sock.makefile('rw')
fd.write('GET /a*b@%40%233 HTTP/1.1\r\nHost: localhost\r\nConnection: '\ fd.write('GET /a*b@%40%233 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n')
'close\r\n\r\n')
fd.flush() fd.flush()
result = read_http(sock) result = read_http(sock)
self.assertEqual(result.status, 'HTTP/1.1 200 OK') self.assertEqual(result.status, 'HTTP/1.1 200 OK')
@@ -1148,6 +1161,7 @@ class TestHttpd(_TestBase):
def test_debug(self): def test_debug(self):
self.spawn_server(debug=False) self.spawn_server(debug=False)
def crasher(env, start_response): def crasher(env, start_response):
raise RuntimeError("intentional crash") raise RuntimeError("intentional crash")
self.site.application = crasher self.site.application = crasher
@@ -1238,6 +1252,7 @@ class TestHttpd(_TestBase):
# #
# https://github.com/eventlet/eventlet/issues/80 # https://github.com/eventlet/eventlet/issues/80
random_case_header = ('eTAg', 'TAg-VAluE') random_case_header = ('eTAg', 'TAg-VAluE')
def wsgi_app(environ, start_response): def wsgi_app(environ, start_response):
start_response('200 oK', [random_case_header]) start_response('200 oK', [random_case_header])
return [''] return ['']
@@ -1306,7 +1321,7 @@ class IterableAlreadyHandledTest(_TestBase):
result = read_http(sock) result = read_http(sock)
self.assertEqual(result.status, 'HTTP/1.1 200 OK') self.assertEqual(result.status, 'HTTP/1.1 200 OK')
self.assertEqual(result.headers_lower.get('transfer-encoding'), 'chunked') self.assertEqual(result.headers_lower.get('transfer-encoding'), 'chunked')
self.assertEqual(result.body, '0\r\n\r\n') # Still coming back chunked self.assertEqual(result.body, '0\r\n\r\n') # Still coming back chunked
class ProxiedIterableAlreadyHandledTest(IterableAlreadyHandledTest): class ProxiedIterableAlreadyHandledTest(IterableAlreadyHandledTest):
@@ -1314,11 +1329,9 @@ class ProxiedIterableAlreadyHandledTest(IterableAlreadyHandledTest):
# results as well as regular ones # results as well as regular ones
@skip_with_pyevent @skip_with_pyevent
def get_app(self): def get_app(self):
from eventlet import tpool
return tpool.Proxy(super(ProxiedIterableAlreadyHandledTest, self).get_app()) return tpool.Proxy(super(ProxiedIterableAlreadyHandledTest, self).get_app())
def tearDown(self): def tearDown(self):
from eventlet import tpool
tpool.killall() tpool.killall()
super(ProxiedIterableAlreadyHandledTest, self).tearDown() super(ProxiedIterableAlreadyHandledTest, self).tearDown()
@@ -1326,19 +1339,20 @@ class ProxiedIterableAlreadyHandledTest(IterableAlreadyHandledTest):
class TestChunkedInput(_TestBase): class TestChunkedInput(_TestBase):
dirt = "" dirt = ""
validator = None validator = None
def application(self, env, start_response): def application(self, env, start_response):
input = env['wsgi.input'] input = env['wsgi.input']
response = [] response = []
pi = env["PATH_INFO"] pi = env["PATH_INFO"]
if pi=="/short-read": if pi == "/short-read":
d=input.read(10) d = input.read(10)
response = [d] response = [d]
elif pi=="/lines": elif pi == "/lines":
for x in input: for x in input:
response.append(x) response.append(x)
elif pi=="/ping": elif pi == "/ping":
input.read() input.read()
response.append("pong") response.append("pong")
elif pi.startswith("/yield_spaces"): elif pi.startswith("/yield_spaces"):
@@ -1485,9 +1499,8 @@ class TestChunkedInput(_TestBase):
self.assert_(False) self.assert_(False)
def test_close_before_finished(self): def test_close_before_finished(self):
import signal
got_signal = [] got_signal = []
def handler(*args): def handler(*args):
got_signal.append(1) got_signal.append(1)
raise KeyboardInterrupt() raise KeyboardInterrupt()
@@ -1511,4 +1524,4 @@ class TestChunkedInput(_TestBase):
if __name__ == '__main__': if __name__ == '__main__':
main() unittest.main()

31
tox.ini
View File

@@ -9,6 +9,7 @@ max-line-length = 101
exclude = *.egg*,.env,.git,.hg,.tox,_*,build*,dist*,venv* exclude = *.egg*,.env,.git,.hg,.tox,_*,build*,dist*,venv*
ignore = E261 ignore = E261
max-line-length = 101 max-line-length = 101
show-source = 1
[tox] [tox]
envlist = envlist =
@@ -21,10 +22,38 @@ envlist =
downloadcache = {toxworkdir}/pip_download_cache downloadcache = {toxworkdir}/pip_download_cache
deps = deps =
nose==1.3.1 nose==1.3.1
pyopenssl==0.13 pep8==1.5.6
psycopg2cffi-compat==1.1 psycopg2cffi-compat==1.1
pyopenssl==0.13
pyzmq==13.1.0 pyzmq==13.1.0
# For now, PEP-8 check certain files known to be clean
# TODO: fix the rest of PEP-8 errors, leave only 'pep8 benchmarks/ eventlet/ tests/'
commands = commands =
pep8 \
benchmarks/__init__.py \
benchmarks/context.py \
eventlet/__init__.py \
eventlet/backdoor.py \
eventlet/debug.py \
eventlet/green/__init__.py \
eventlet/green/_socket_nodns.py \
eventlet/green/ftplib.py \
eventlet/green/OpenSSL/__init__.py \
eventlet/green/subprocess.py \
eventlet/green/time.py \
eventlet/hubs/__init__.py \
eventlet/hubs/timer.py \
eventlet/semaphore.py \
eventlet/support/__init__.py \
tests/__init__.py \
tests/backdoor_test.py \
tests/fork_test.py \
tests/greendns_test.py \
tests/nosewrapper.py \
tests/semaphore_test.py \
tests/stdlib/test_thread.py \
tests/stdlib/test_threading.py \
tests/wsgi_test_conntimeout.py
nosetests --verbose tests/ nosetests --verbose tests/
nosetests --verbose --with-doctest eventlet/coros.py eventlet/event.py \ nosetests --verbose --with-doctest eventlet/coros.py eventlet/event.py \
eventlet/pool.py eventlet/pools.py eventlet/proc.py \ eventlet/pool.py eventlet/pools.py eventlet/proc.py \