def test_as_future_immediate_none(framework): ''' Returning None immediately from as_future ''' errors = [] results = [] calls = [] def method(*args, **kw): calls.append((args, kw)) return None f = txaio.as_future(method, 1, 2, 3, key='word') def cb(x): results.append(x) def errback(f): errors.append(f) txaio.add_callbacks(f, cb, errback) run_once() assert len(results) == 1 assert len(errors) == 0 assert results[0] is None assert calls[0] == ((1, 2, 3), dict(key='word'))
def test_errback_without_except(framework): ''' Create a failure without an except block ''' f = txaio.create_future() exception = RuntimeError("it failed") errors = [] def err(f): errors.append(f) txaio.add_callbacks(f, None, err) fail = txaio.create_failure(exception) txaio.reject(f, fail) run_once() assert len(errors) == 1 assert isinstance(errors[0], txaio.IFailedFuture) tb = txaio.failure_format_traceback(errors[0]) assert 'RuntimeError' in tb assert 'it failed' in tb assert txaio.failure_message(errors[0]) == 'RuntimeError: it failed' assert 'it failed' in str(errors[0])
def test_as_future_exception(framework): ''' Raises an exception from as_future ''' errors = [] results = [] calls = [] exception = RuntimeError("sadness") def method(*args, **kw): calls.append((args, kw)) raise exception f = txaio.as_future(method, 1, 2, 3, key='word') def cb(x): results.append(x) def errback(f): errors.append(f) txaio.add_callbacks(f, cb, errback) run_once() assert len(results) == 0 assert len(errors) == 1 assert errors[0].value == exception assert calls[0] == ((1, 2, 3), dict(key='word'))
def test_create_future_failure_explicit_loop(framework): """ process events on alternate loop= for create_future later """ pytest.importorskip('asyncio') if txaio.using_twisted: pytest.skip() import asyncio alt_loop = asyncio.new_event_loop() the_exception = Exception('bad') txa = txaio.with_config(loop=alt_loop) f = txa.create_future_error(the_exception) results = [] def boom(r): try: results.append(r.result()) except Exception as e: results.append(e) f.add_done_callback(boom) # run_once() runs the txaio.config.loop so we shouldn't get any # results until we spin alt_loop assert results == [] run_once() assert results == [] with replace_loop(alt_loop): run_once() assert results == [the_exception]
def test_create_future_explicit_loop(framework): """ process events on alternate loop= for create_future later """ pytest.importorskip('asyncio') if txaio.using_twisted: pytest.skip() import asyncio alt_loop = asyncio.new_event_loop() txa = txaio.with_config(loop=alt_loop) f = txa.create_future() results = [] f.add_done_callback(lambda r: results.append(r.result())) assert results == [] txaio.resolve(f, 'some result') # run_once() runs the txaio.config.loop so we shouldn't get any # results until we spin alt_loop assert results == [] run_once() assert results == [] with replace_loop(alt_loop): run_once() assert results == ['some result']
def test_as_future_recursive(framework): ''' Returns another Future from as_future ''' errors = [] results = [] calls = [] f1 = txaio.create_future_success(42) def method(*args, **kw): calls.append((args, kw)) return f1 f0 = txaio.as_future(method, 1, 2, 3, key='word') def cb(x): results.append(x) def errback(f): errors.append(f) txaio.add_callbacks(f0, cb, errback) run_once() assert len(results) == 1 assert len(errors) == 0 assert results[0] == 42 assert calls[0] == ((1, 2, 3), dict(key='word'))
def test_errback(framework): f = txaio.create_future() exception = RuntimeError("it failed") errors = [] def err(f): errors.append(f) txaio.add_callbacks(f, None, err) try: raise exception except: fail = txaio.create_failure() txaio.reject(f, fail) run_once() assert len(errors) == 1 assert isinstance(errors[0], txaio.IFailedFuture) assert exception == errors[0].value assert txaio.failure_traceback(errors[0]) is not None tb = txaio.failure_format_traceback(errors[0]) assert 'RuntimeError' in tb assert 'it failed' in tb assert txaio.failure_message(errors[0]) == 'RuntimeError: it failed' assert 'it failed' in str(errors[0])
def test_errback_reject_no_args(): """ txaio.reject() with no args """ f = txaio.create_future() exception = RuntimeError("it failed") errors = [] def err(f): errors.append(f) txaio.add_callbacks(f, None, err) try: raise exception except: txaio.reject(f) run_once() assert len(errors) == 1 assert isinstance(errors[0], txaio.IFailedFuture) assert exception == errors[0].value tb = txaio.failure_format_traceback(errors[0]) assert 'RuntimeError' in tb assert 'it failed' in tb assert txaio.failure_message(errors[0]) == 'RuntimeError: it failed' assert 'it failed' in str(errors[0])
def test_errback_cancel_exception(framework): ''' reject a future with a CancelledError ''' f = txaio.create_future() errors = [] def err(f): errors.append(f) txaio.add_callbacks(f, None, err) txaio.cancel(f, msg="future cancelled") run_once() assert len(errors) == 1 assert isinstance(errors[0], txaio.IFailedFuture) tb = txaio.failure_format_traceback(errors[0]) assert 'CancelledError' in tb if txaio.using_asyncio and sys.version_info >= (3, 9): assert txaio.failure_message( errors[0]) == 'CancelledError: future cancelled' assert 'future cancelled' in str(errors[0]) else: assert txaio.failure_message(errors[0]) == 'CancelledError: '
def test_immediate_result(framework): f = txaio.create_future_success("it worked") results = [] def cb(f): results.append(f) txaio.add_callbacks(f, cb, None) run_once() assert len(results) == 1 assert results[0] == "it worked"
def test_callback(framework): f = txaio.create_future() results = [] def cb(f): results.append(f) txaio.add_callbacks(f, cb, None) txaio.resolve(f, "it worked") run_once() assert len(results) == 1 assert results[0] == "it worked"
def test_cancel(framework): cancels = [] def it_died(f): cancels.append(f) f = txaio.create_future(canceller=it_died) # both Future and Deferred have .cancel() methods .. but seemed # more "symmetric"/expected to make a method? But could just stick # with "f.cancel()" here ... txaio.cancel(f) # at least for Twisted, we have to "handle" the "CancelledError" # -- in practice, dropping a future on the floor with no # error-handler is A Bad Thing anyway txaio.add_callbacks(f, None, lambda _: None) run_once() run_once() assert cancels == [f]
def test_immediate_failure(framework): exception = RuntimeError("it failed") try: raise exception except: f0 = txaio.create_future_error() fail = txaio.create_failure() errors = [] results = [] f1 = txaio.create_future_error(fail) def cb(x): results.append(x) def errback(f): errors.append(f) txaio.add_callbacks(f0, cb, errback) txaio.add_callbacks(f1, cb, errback) run_once() run_once() run_once() assert len(results) == 0 assert len(errors) == 2 assert isinstance(errors[0], txaio.IFailedFuture) assert isinstance(errors[1], txaio.IFailedFuture) assert errors[0].value == exception assert errors[1].value == exception # should be distinct FailedPromise instances assert id(errors[0]) != id(errors[1])
def test_as_future_coroutine(framework): ''' call a coroutine (asyncio) ''' pytest.importorskip('asyncio') # can import asyncio on python3.4, but might still be using # twisted if not txaio.using_asyncio: return errors = [] results = [] calls = [] from asyncio import coroutine @coroutine def method(*args, **kw): calls.append((args, kw)) return 42 f = txaio.as_future(method, 1, 2, 3, key='word') def cb(x): results.append(x) def errback(f): errors.append(f) txaio.add_callbacks(f, cb, errback) run_once() run_once() assert len(results) == 1 assert len(errors) == 0 assert results[0] == 42 assert calls[0] == ((1, 2, 3), dict(key='word'))
def test_chained_callback(framework): """ Chain two callbacks where the first one alters the value. """ calls = [] def callback0(arg): calls.append(arg) return arg + " pray I do not alter it futher" def callback1(arg): calls.append(arg) f = txaio.create_future() txaio.add_callbacks(f, callback0, None) txaio.add_callbacks(f, callback1, None) txaio.resolve(f, "the deal") run_once() assert len(calls) == 2 assert calls[0] == "the deal" assert calls[1] == "the deal pray I do not alter it futher"
def test_errback_plain_exception(framework): ''' reject a future with just an Exception ''' f = txaio.create_future() exception = RuntimeError("it failed") errors = [] def err(f): errors.append(f) txaio.add_callbacks(f, None, err) txaio.reject(f, exception) run_once() assert len(errors) == 1 assert isinstance(errors[0], txaio.IFailedFuture) tb = txaio.failure_format_traceback(errors[0]) assert 'RuntimeError' in tb assert 'it failed' in tb assert txaio.failure_message(errors[0]) == 'RuntimeError: it failed' assert 'it failed' in str(errors[0])
def test_errback_without_except(): ''' Create a failure without an except block ''' f = txaio.create_future() exception = RuntimeError("it failed") errors = [] def err(f): errors.append(f) txaio.add_callbacks(f, None, err) fail = txaio.create_failure(exception) txaio.reject(f, fail) run_once() assert len(errors) == 1 assert isinstance(errors[0], txaio.IFailedFuture) tb = txaio.failure_format_traceback(errors[0]) assert 'RuntimeError' in tb assert 'it failed' in tb assert txaio.failure_message(errors[0]) == 'RuntimeError: it failed' assert 'it failed' in str(errors[0])