oggit/packages/flask-executor/opengnsys-flask-executor-0..../tests/test_futures.py

98 lines
3.0 KiB
Python

import concurrent.futures
import time
import pytest
from flask_executor import Executor
from flask_executor.futures import FutureCollection, FutureProxy
from flask_executor.helpers import InstanceProxy
def fib(n):
if n <= 2:
return 1
else:
return fib(n-1) + fib(n-2)
def test_plain_future():
executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
futures = FutureCollection()
future = executor.submit(fib, 33)
futures.add('fibonacci', future)
assert futures.done('fibonacci') is False
assert futures._state('fibonacci') is not None
assert future in futures
futures.pop('fibonacci')
assert future not in futures
def test_missing_future():
futures = FutureCollection()
assert futures.running('test') is None
def test_duplicate_add_future():
executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
futures = FutureCollection()
future = executor.submit(fib, 33)
futures.add('fibonacci', future)
try:
futures.add('fibonacci', future)
except ValueError:
assert True
else:
assert False
def test_futures_max_length():
executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
futures = FutureCollection(max_length=10)
future = executor.submit(pow, 2, 4)
futures.add(0, future)
assert future in futures
assert len(futures) == 1
for i in range(1, 11):
futures.add(i, executor.submit(pow, 2, 4))
assert len(futures) == 10
assert future not in futures
def test_future_proxy(default_app):
executor = Executor(default_app)
with default_app.test_request_context(''):
future = executor.submit(pow, 2, 4)
# Test if we're returning a subclass of Future
assert isinstance(future, concurrent.futures.Future)
assert isinstance(future, FutureProxy)
concurrent.futures.wait([future])
# test standard Future methods and attributes
assert future._state == concurrent.futures._base.FINISHED
assert future.done()
assert future.exception(timeout=0) is None
def test_add_done_callback(default_app):
"""Exceptions thrown in callbacks can't be easily caught and make it hard
to test for callback failure. To combat this, a global variable is used to
store the value of an exception and test for its existence.
"""
executor = Executor(default_app)
global exception
exception = None
with default_app.test_request_context(''):
future = executor.submit(time.sleep, 0.5)
def callback(future):
global exception
try:
executor.submit(time.sleep, 0)
except RuntimeError as e:
exception = e
future.add_done_callback(callback)
concurrent.futures.wait([future])
assert exception is None
def test_instance_proxy():
class TestProxy(InstanceProxy):
pass
x = TestProxy(concurrent.futures.Future())
assert isinstance(x, concurrent.futures.Future)
assert 'TestProxy' in repr(x)
assert 'Future' in repr(x)