def test_process_workers(app):
    app.config['EXECUTOR_TYPE'] = 'process'
    app.config['EXECUTOR_MAX_WORKERS'] = EXECUTOR_MAX_WORKERS
    executor = Executor(app)
    with app.app_context():
        executor.submit(fib, 5)
        assert executor._executor._max_workers == EXECUTOR_MAX_WORKERS
Exemple #2
0
def test_process_executor():
    app = Flask(__name__)
    app.config['EXECUTOR_TYPE'] = 'process'
    executor = Executor(app)
    with app.app_context():
        executor.submit(fib, 5)
        assert type(executor._executor) == concurrent.futures.ProcessPoolExecutor
Exemple #3
0
def test_thread_workers():
    app = Flask(__name__)
    app.config['EXECUTOR_TYPE'] = 'thread'
    app.config['EXECUTOR_MAX_WORKERS'] = EXECUTOR_MAX_WORKERS
    executor = Executor(app)
    with app.app_context():
        executor.submit(fib, 5)
        assert executor._executor._max_workers == EXECUTOR_MAX_WORKERS
def test_submit_app_context(app):
    test_value = random.randint(1, 101)
    app.config['TEST_VALUE'] = test_value
    executor = Executor(app)
    with app.test_request_context(''):
        future = executor.submit(app_context_test_value)
    assert future.result() == test_value
def test_futures_as_completed(default_app):
    executor = Executor(default_app)
    with default_app.test_request_context(''):
        futures = {executor.submit(fib, x): x for x in range(30)}
        for future in concurrent.futures.as_completed(futures):
            x = futures[future]
            assert future.result() == fib(x)
def test_submit_request_context(app):
    test_value = random.randint(1, 101)
    executor = Executor(app)
    with app.test_request_context(''):
        request.test_value = test_value
        future = executor.submit(request_context_test_value)
    assert future.result() == test_value
def test_submit_g_context_process(default_app):
    test_value = random.randint(1, 101)
    executor = Executor(default_app)
    with default_app.test_request_context(''):
        g.test_value = test_value
        future = executor.submit(g_context_test_value)
    assert future.result() == test_value
Exemple #8
0
def test_submit_result():
    app = Flask(__name__)
    executor = Executor(app)
    with app.app_context():
        future = executor.submit(fib, 5)
        assert type(future) == concurrent.futures.Future
        assert future.result() == fib(5)
Exemple #9
0
def test_default_done_callback(app):
    executor = Executor(app)
    def callback(future):
        setattr(future, 'test', 'test')
    executor.add_default_done_callback(callback)
    with app.test_request_context('/'):
        future = executor.submit(fib, 5)
        concurrent.futures.wait([future])
        assert hasattr(future, 'test')
Exemple #10
0
def test_propagate_exception_callback(app):
    app.config['EXECUTOR_PROPAGATE_EXCEPTIONS'] = True
    executor = Executor(app)
    with pytest.raises(NameError):
        with app.test_request_context('/'):
            future = executor.submit(fail)
            concurrent.futures.wait([future])
            assert propagate_exceptions_callback in future._done_callbacks
            propagate_exceptions_callback(future)
def test_teardown_appcontext_is_called(default_app):
    default_app.config['EXECUTOR_MAX_WORKERS'] = 1
    default_app.config['EXECUTOR_PUSH_APP_CONTEXT'] = True
    default_app.teardown_appcontext(clear_thread_local)

    executor = Executor(default_app)
    with default_app.test_request_context():
        futures = [executor.submit(set_thread_local) for _ in range(2)]
        concurrent.futures.wait(futures)
        [propagate_exceptions_callback(future) for future in futures]
def test_propagate_exception_callback(app, caplog):
    caplog.set_level(logging.ERROR)
    app.config['EXECUTOR_PROPAGATE_EXCEPTIONS'] = True
    executor = Executor(app)
    with pytest.raises(NameError):
        with app.test_request_context('/'):
            future = executor.submit(fail)
            assert propagate_exceptions_callback in future._done_callbacks
            concurrent.futures.wait([future])
            future.result()
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_teardown_appcontext_is_not_called(default_app):
    default_app.config['EXECUTOR_MAX_WORKERS'] = 1
    default_app.config['EXECUTOR_PUSH_APP_CONTEXT'] = False
    default_app.teardown_appcontext(clear_thread_local)

    executor = Executor(default_app)
    with pytest.raises(ValueError):
        with default_app.test_request_context():
            for i in range(2):
                future = executor.submit(set_thread_local)
                concurrent.futures.wait([future])
                propagate_exceptions_callback(future)
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_sqlalchemy(default_app, caplog):
    default_app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {'echo_pool': 'debug', 'echo': 'debug'}
    default_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
    default_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    default_app.config['EXECUTOR_PUSH_APP_CONTEXT'] = True
    default_app.config['EXECUTOR_MAX_WORKERS'] = 1
    db = flask_sqlalchemy.SQLAlchemy(default_app)

    def test_db():
        return list(db.session.execute('select 1'))

    executor = Executor(default_app)
    with default_app.test_request_context():
        for i in range(2):
            with caplog.at_level('DEBUG'):
                caplog.clear()
                future = executor.submit(test_db)
                concurrent.futures.wait([future])
                future.result()
                assert 'checked out from pool' in caplog.text
                assert 'being returned to pool' in caplog.text
Exemple #17
0
def test_default_executor():
    app = Flask(__name__)
    executor = Executor(app)
    with app.app_context():
        executor.submit(fib, 5)
        assert type(executor._executor) == concurrent.futures.ThreadPoolExecutor
def test_submit(app):
    executor = Executor(app)
    future = executor.submit(fib, 5)
    assert future.result() == fib(5)
def test_submit(app):
    executor = Executor(app)
    with app.test_request_context(''):
        future = executor.submit(fib, 5)
    assert future.result() == fib(5)
def test_named_executor_submit(app):
    name = 'custom'
    custom_executor = Executor(app, name=name)
    with app.test_request_context(''):
        future = custom_executor.submit(fib, 5)
    assert future.result() == fib(5)
def test_thread_executor(app):
    app.config['EXECUTOR_TYPE'] = 'thread'
    executor = Executor(app)
    with app.app_context():
        executor.submit(fib, 5)
        assert type(executor._executor) == concurrent.futures.ThreadPoolExecutor