diff --git a/tests/test_infected_asyncio.py b/tests/test_infected_asyncio.py index 9f6b43e5..e13df325 100644 --- a/tests/test_infected_asyncio.py +++ b/tests/test_infected_asyncio.py @@ -183,6 +183,7 @@ def test_tractor_cancels_aio( async def main(): async with tractor.open_nursery( debug_mode=debug_mode, + registry_addrs=[reg_addr], ) as an: portal = await an.run_in_actor( asyncio_actor, @@ -205,11 +206,11 @@ def test_trio_cancels_aio( ''' async def main(): - + # cancel the nursery shortly after boot with trio.move_on_after(1): - # cancel the nursery shortly after boot - - async with tractor.open_nursery() as tn: + async with tractor.open_nursery( + registry_addrs=[reg_addr], + ) as tn: await tn.run_in_actor( asyncio_actor, target='aio_sleep_forever', @@ -277,7 +278,9 @@ def test_context_spawns_aio_task_that_errors( ''' async def main(): with trio.fail_after(1 + delay): - async with tractor.open_nursery() as an: + async with tractor.open_nursery( + registry_addrs=[reg_addr], + ) as an: p = await an.start_actor( 'aio_daemon', enable_modules=[__name__], @@ -360,7 +363,9 @@ def test_aio_cancelled_from_aio_causes_trio_cancelled( async def main(): an: tractor.ActorNursery - async with tractor.open_nursery() as an: + async with tractor.open_nursery( + registry_addrs=[reg_addr], + ) as an: p: tractor.Portal = await an.run_in_actor( asyncio_actor, target='aio_cancel', @@ -569,7 +574,9 @@ def test_basic_interloop_channel_stream( async def main(): # TODO, figure out min timeout here! with trio.fail_after(6): - async with tractor.open_nursery() as an: + async with tractor.open_nursery( + registry_addrs=[reg_addr], + ) as an: portal = await an.run_in_actor( stream_from_aio, infect_asyncio=True, @@ -582,9 +589,13 @@ def test_basic_interloop_channel_stream( # TODO: parametrize the above test and avoid the duplication here? -def test_trio_error_cancels_intertask_chan(reg_addr): +def test_trio_error_cancels_intertask_chan( + reg_addr: tuple[str, int], +): async def main(): - async with tractor.open_nursery() as an: + async with tractor.open_nursery( + registry_addrs=[reg_addr], + ) as an: portal = await an.run_in_actor( stream_from_aio, trio_raise_err=True, @@ -619,6 +630,7 @@ def test_trio_closes_early_causes_aio_checkpoint_raise( async with tractor.open_nursery( debug_mode=debug_mode, # enable_stack_on_sig=True, + registry_addrs=[reg_addr], ) as an: portal = await an.run_in_actor( stream_from_aio, @@ -667,6 +679,7 @@ def test_aio_exits_early_relays_AsyncioTaskExited( async def main(): with trio.fail_after(1 + delay): async with tractor.open_nursery( + registry_addrs=[reg_addr], debug_mode=debug_mode, # enable_stack_on_sig=True, ) as an: @@ -707,6 +720,7 @@ def test_aio_errors_and_channel_propagates_and_closes( ): async def main(): async with tractor.open_nursery( + registry_addrs=[reg_addr], debug_mode=debug_mode, ) as an: portal = await an.run_in_actor( @@ -806,6 +820,7 @@ def test_echoserver_detailed_mechanics( ): async def main(): async with tractor.open_nursery( + registry_addrs=[reg_addr], debug_mode=debug_mode, ) as an: p = await an.start_actor( @@ -984,7 +999,7 @@ async def manage_file( ], ids=[ 'bg_aio_task', - 'just_trio_slee', + 'just_trio_sleep', ], ) @pytest.mark.parametrize( @@ -1000,11 +1015,14 @@ async def manage_file( ) def test_sigint_closes_lifetime_stack( tmp_path: Path, + reg_addr: tuple, + debug_mode: bool, + wait_for_ctx: bool, bg_aio_task: bool, trio_side_is_shielded: bool, - debug_mode: bool, send_sigint_to: str, + start_method: str, ): ''' Ensure that an infected child can use the `Actor.lifetime_stack` @@ -1014,12 +1032,22 @@ def test_sigint_closes_lifetime_stack( ''' async def main(): - delay = 999 if tractor.debug_mode() else 1 + delay: float = ( + 999 + if debug_mode + else 1 + ) try: an: tractor.ActorNursery async with tractor.open_nursery( + registry_addrs=[reg_addr], debug_mode=debug_mode, ) as an: + + # sanity + if debug_mode: + assert tractor.debug_mode() + p: tractor.Portal = await an.start_actor( 'file_mngr', enable_modules=[__name__], @@ -1054,6 +1082,10 @@ def test_sigint_closes_lifetime_stack( cpid if send_sigint_to == 'child' else os.getpid() ) + print( + f'Sending SIGINT to {send_sigint_to!r}\n' + f'pid: {pid!r}\n' + ) os.kill( pid, signal.SIGINT, @@ -1064,13 +1096,37 @@ def test_sigint_closes_lifetime_stack( # timeout should trigger! if wait_for_ctx: print('waiting for ctx outcome in parent..') + + if debug_mode: + assert delay == 999 + try: - with trio.fail_after(1 + delay): + with trio.fail_after( + 1 + delay + ): await ctx.wait_for_result() except tractor.ContextCancelled as ctxc: assert ctxc.canceller == ctx.chan.uid raise + except trio.TooSlowError: + if ( + send_sigint_to == 'child' + and + start_method == 'subint_forkserver' + ): + pytest.xfail( + reason=( + 'SIGINT delivery to fork-child subactor is known ' + 'to NOT SUCCEED, precisely bc we have not wired up a' + '"trio SIGINT mode" in the child pre-fork.\n' + 'Also see `test_orphaned_subactor_sigint_cleanup_DRAFT` for' + 'a dedicated suite demonstrating this expected limitation as ' + 'well as the detailed doc:\n' + '`ai/conc-anal/subint_forkserver_orphan_sigint_hang_issue.md`.\n' + ), + ) + # XXX CASE 2: this seems to be the source of the # original issue which exhibited BEFORE we put # a `Actor.cancel_soon()` inside @@ -1170,6 +1226,7 @@ def test_aio_side_raises_before_started( with trio.fail_after(3): an: tractor.ActorNursery async with tractor.open_nursery( + registry_addrs=[reg_addr], debug_mode=debug_mode, loglevel=loglevel, ) as an: