Skip to content

Instantly share code, notes, and snippets.

@imankulov
Created June 10, 2014 08:57
Show Gist options
  • Save imankulov/6f424113fb4748ad0d76 to your computer and use it in GitHub Desktop.
Save imankulov/6f424113fb4748ad0d76 to your computer and use it in GitHub Desktop.
Test generator and releaser which know how to create fixtures in separate threads
"""
Generator and Releaser objects which could be used to create and destroy
objects in separate threads. Generator constantly keeps the pool of N objects
to use by the test function (by default N equals to 1).
How to use them:
You create a session-scope generator and releaser. They are subclasses
of threading.Thread, so you should start them as well.
.. code-block:: python
@pytest.fixture(scope='session')
def item_generator():
def create():
# a time-consuming process of making the object
return <the object>
gen = Generator(create)
gen.start()
return gen
@pytest.fixture(scope='session')
def item_releaser():
def release(obj):
# it should accept the object and destroy it without raising any exceptions
pass
rel = Releaser(release)
rel.start()
return rel
As you are done with it, create a function-scoped fixture, which gets the
object from the generator, yelds it, and return it back to releaser
.. code-block:: python
@pytest.yield_fixture
def item(item_generator, item_releaser):
item = item_generator.get()
yield item
item_releaser.put(item)
"""
import threading
from Queue import Queue
class Generator(threading.Thread):
def __init__(self, func, max_elements=1):
threading.Thread.__init__(self)
self.daemon = True
self.func = func
self.queue = Queue(maxsize=max_elements)
def run(self):
while True:
try:
element = self.func()
except Exception as e:
self.queue.put(e)
else:
self.queue.put(element)
def get(self):
element = self.queue.get()
if isinstance(element, Exception):
raise element
return element
class Releaser(threading.Thread):
def __init__(self, func):
threading.Thread.__init__(self)
self.daemon = True
self.func = func
self.queue = Queue()
def run(self):
while True:
element = self.queue.get()
try:
self.func(element)
except Exception:
import traceback
traceback.print_exc()
def put(self, element):
return self.queue.put(element)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment