Created
June 10, 2014 08:57
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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