Hub selection via environment variable obviates the need for the eventlethub. Fixed up docs to refer to it.

This commit is contained in:
Ryan Williams
2010-02-21 14:23:20 -05:00
parent 57d12ec6d4
commit dba52d1fec
6 changed files with 12 additions and 85 deletions

View File

@@ -1,3 +1,5 @@
.. _understanding_hubs:
Understanding Eventlet Hubs
===========================

View File

@@ -19,7 +19,7 @@ Lastly, you can just use nose directly if you want:
$ nosetests
That's it! The output from running nose is the same as unittest's output, if the entire directory was one big test file. It tends to emit a lot of tracebacks from a few noisy tests, but they still pass.
That's it! The output from running nose is the same as unittest's output, if the entire directory was one big test file.
Many tests are skipped based on environmental factors; for example, it makes no sense to test Twisted-specific functionality when Twisted is not installed. These are printed as S's during execution, and in the summary printed after the tests run it will tell you how many were skipped.
@@ -51,22 +51,14 @@ That will run all the tests, though the output will be a little weird because it
Testing Eventlet Hubs
---------------------
When you run the tests, Eventlet will use the most appropriate hub for the current platform to do its dispatch. It's sometimes useful when making changes to Eventlet to test those changes on hubs other than the default. You can do this with the eventlethub nose plugin. The plugin is not installed in your system, so in order to get Nose to see it, we have to call a wrapper script instead of Nose:
When you run the tests, Eventlet will use the most appropriate hub for the current platform to do its dispatch. It's sometimes useful when making changes to Eventlet to test those changes on hubs other than the default. You can do this with the ``EVENTLET_HUB`` environment variable.
.. code-block:: sh
$ python tests/nosewrapper.py --with-eventlethub --hub=selects
``nosewrapper.py`` takes exactly the same arguments as nosetests, and behaves exactly the same way. Here's what the two arguments mean:
$ EVENTLET_HUB=epolls nosetests
* ``--with-eventlethub`` enables the eventlethub plugin.
* ``--hub=HUB`` specifies which Eventlet hub to use during the tests.
See :ref:`understanding_hubs` for the full list of hubs.
If you wish to run tests against a particular Twisted reactor, use ``--reactor=REACTOR`` instead of ``--hub``. The full list of eventlet hubs is currently:
* poll
* selects
* pyevent (requires pyevent installed on your system)
Writing Tests
-------------
@@ -77,8 +69,8 @@ The filename convention when writing a test for module `foo` is to name the test
If you are writing a test that involves a client connecting to a spawned server, it is best to not use a hardcoded port because that makes it harder to parallelize tests. Instead bind the server to 0, and then look up its port when connecting the client, like this::
server_sock = api.tcp_listener(('127.0.0.1', 0))
client_sock = api.connect_tcp(('localhost', server_sock.getsockname()[1]))
server_sock = eventlet.listener(('127.0.0.1', 0))
client_sock = eventlet.connect(('localhost', server_sock.getsockname()[1]))
Coverage
--------

View File

@@ -1,4 +1,5 @@
import sys
import os
from eventlet.support import greenlets as greenlet
from eventlet import patcher
@@ -58,6 +59,8 @@ def use_hub(mod=None):
initialization, because it resets the hub's state and any existing
timers or listeners will never be resumed.
"""
if mod is None:
mod = os.environ.get('EVENTLET_HUB', None)
if mod is None:
mod = get_default_hub()
if hasattr(_threadlocal, 'hub'):

View File

@@ -24,7 +24,6 @@ def check_hub():
class TestApi(TestCase):
mode = 'static'
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')

View File

@@ -1,68 +0,0 @@
import logging
from nose.plugins.base import Plugin
from eventlet import hubs
log = logging.getLogger('nose.plugins.eventlethub')
class EventletHub(Plugin):
name = 'eventlethub'
def options(self, parser, env):
super(EventletHub, self).options(parser, env)
parser.add_option('--hub',
dest="eventlet_hub",
metavar="HUB",
default=env.get('NOSE_EVENTLET_HUB'),
help="Use the specified eventlet hub for the tests."\
" [NOSE_EVENTLET_HUB]")
parser.add_option('--reactor',
dest="eventlet_reactor",
metavar="REACTOR",
default=env.get('NOSE_EVENTLET_REACTOR'),
help="Use the specified Twisted reactor for the "\
"tests. Use of this flag forces the twisted hub, "\
"as if --hub=twistedr was also supplied. "\
"[NOSE_EVENTLET_REACTOR]")
def configure(self, options, config):
super(EventletHub, self).configure(options, config)
if options.eventlet_reactor is not None:
self.hub_name = 'twistedr'
self.reactor = options.eventlet_reactor
else:
self.hub_name = options.eventlet_hub
self.reactor = None
if self.hub_name == 'twistedr':
self.twisted_already_used = False
if self.reactor is None:
raise ValueError("Can't have twisted hub without specifying a "\
"reactor. Use --reactor instead.")
m = __import__('twisted.internet.' + self.reactor)
getattr(m.internet, self.reactor).install()
def help(self):
return "Allows selection of a specific eventlet hub via the "\
"--eventlet-hub command-line option. If no hub is explicitly "\
" specified, the default hub for the current configuration is printed "\
" and used."
def begin(self):
"""Select the desired hub.
"""
if self.hub_name is None:
log.warn('Using default eventlet hub: %s, did you mean '\
'to supply --hub command line argument?',
hubs.get_hub().__module__)
else:
if self.hub_name == 'twistedr':
if self.twisted_already_used:
return
else:
self.twisted_already_used = True
hubs.use_hub(self.hub_name)
log.info('using hub %s', hubs.get_hub())

View File

@@ -22,5 +22,4 @@ if zero_status in argv:
else:
launch = nose.main
from tests import eventlethub
launch(addplugins=[eventlethub.EventletHub()], argv=argv)
launch(argv=argv)