tractor/tests/test_infected_asyncio.py

117 lines
2.4 KiB
Python
Raw Normal View History

2021-11-05 14:42:43 +00:00
'''
The most hipster way to force SC onto the stdlib's "async".
'''
2021-11-07 22:05:40 +00:00
from typing import Optional
import asyncio
2021-11-07 22:05:40 +00:00
import builtins
import importlib
import pytest
2021-11-07 22:05:40 +00:00
import trio
import tractor
2021-11-07 22:05:40 +00:00
from tractor import RemoteActorError
2021-11-05 14:42:43 +00:00
async def sleep_and_err():
await asyncio.sleep(0.1)
assert 0
2021-11-07 22:05:40 +00:00
async def sleep_forever():
await asyncio.sleep(float('inf'))
async def asyncio_actor(
target: str,
expect_err: Optional[Exception] = None
) -> None:
assert tractor.current_actor().is_infected_aio()
2021-11-07 22:05:40 +00:00
target = globals()[target]
2021-11-07 22:05:40 +00:00
if '.' in expect_err:
modpath, _, name = expect_err.rpartition('.')
mod = importlib.import_module(modpath)
error = getattr(mod, name)
error = builtins.__dict__.get(expect_err)
try:
# spawn an ``asyncio`` task to run a func and return result
await tractor.to_asyncio.run_task(target)
except Exception as err:
if expect_err:
assert isinstance(err, error)
raise
2021-11-05 14:42:43 +00:00
def test_aio_simple_error(arb_addr):
2021-11-07 22:05:40 +00:00
'''
Verify a simple remote asyncio error propagates back through trio
to the parent actor.
2021-11-07 22:05:40 +00:00
'''
async def main():
2021-11-07 22:05:40 +00:00
async with tractor.open_nursery(
arbiter_addr=arb_addr
) as n:
await n.run_in_actor(
asyncio_actor,
target='sleep_and_err',
expect_err='AssertionError',
infect_asyncio=True,
)
2021-11-07 22:05:40 +00:00
with pytest.raises(RemoteActorError) as excinfo:
trio.run(main)
2021-11-05 14:42:43 +00:00
2021-11-07 22:05:40 +00:00
err = excinfo.value
assert isinstance(err, RemoteActorError)
assert err.type == AssertionError
2021-11-05 14:42:43 +00:00
2021-11-07 22:05:40 +00:00
def test_tractor_cancels_aio(arb_addr):
'''
Verify we can cancel a spawned asyncio task gracefully.
'''
async def main():
async with tractor.open_nursery() as n:
portal = await n.run_in_actor(
asyncio_actor,
target='sleep_forever',
expect_err='asyncio.CancelledError',
infect_asyncio=True,
)
await portal.cancel_actor()
trio.run(main)
2021-11-05 14:42:43 +00:00
def test_aio_cancelled_from_aio_causes_trio_cancelled(arb_addr):
...
def test_trio_cancels_aio(arb_addr):
...
def test_trio_error_cancels_aio(arb_addr):
...
def test_basic_interloop_channel_stream(arb_addr):
...
def test_trio_cancels_and_channel_exits(arb_addr):
...
def test_aio_errors_and_channel_propagates(arb_addr):
...