From 6cab363c513c5cbbaa075354e7e8b24333a5d7af Mon Sep 17 00:00:00 2001 From: goodboy Date: Wed, 11 Feb 2026 18:20:59 -0500 Subject: [PATCH] Catch-n-fail on stale `_root_addrs` state.. Turns out we aren't clearing the `._state._runtime_vars` entries in between `open_root_actor` calls.. This test refinement catches that by adding runtime-vars asserts on the expected root-addrs value; ensure `_runtime_vars['_root_addrs'] ONLY match the values provided by the test's CURRENT root actor. This causes a failure when the (just added) `test_non_registrar_spawns_child` is run as part of the module suite, it's fine when run standalone. --- tests/test_multi_program.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/tests/test_multi_program.py b/tests/test_multi_program.py index ac80928d..eff9a731 100644 --- a/tests/test_multi_program.py +++ b/tests/test_multi_program.py @@ -16,6 +16,8 @@ from tractor._testing import ( tractor_test, ) from tractor import ( + current_actor, + _state, Actor, Context, Portal, @@ -52,7 +54,7 @@ async def test_cancel_remote_arbiter( daemon: subprocess.Popen, reg_addr: UnwrappedAddress, ): - assert not tractor.current_actor().is_arbiter + assert not current_actor().is_arbiter async with tractor.get_registry(reg_addr) as portal: await portal.cancel_actor() @@ -75,7 +77,7 @@ def test_register_duplicate_name( registry_addrs=[reg_addr], ) as an: - assert not tractor.current_actor().is_arbiter + assert not current_actor().is_arbiter p1 = await an.start_actor('doggy') p2 = await an.start_actor('doggy') @@ -99,22 +101,42 @@ async def get_root_portal( and ensure it's contact info is the same as our immediate parent. ''' - await ctx.started() + sub: Actor = current_actor() + rtvs: dict = _state._runtime_vars + raddrs: list[UnwrappedAddress] = rtvs['_root_addrs'] + + # await tractor.pause() + # XXX, in case the sub->root discovery breaks you might need + # this (i know i did Xp)!! + # from tractor.devx import mk_pdb + # mk_pdb().set_trace() + + assert ( + len(raddrs) == 1 + and + list(sub._parent_chan.raddr.unwrap()) in raddrs + ) + + # connect back to our immediate parent which should also + # be the actor-tree's root. from tractor._discovery import get_root ptl: Portal async with get_root() as ptl: root_aid: Aid = ptl.chan.aid - parent_ptl: Portal = tractor.current_actor().get_parent() + parent_ptl: Portal = current_actor().get_parent() assert ( root_aid.name == 'root' and parent_ptl.chan.aid == root_aid ) + await ctx.started() def test_non_registrar_spawns_child( daemon: subprocess.Popen, reg_addr: UnwrappedAddress, + loglevel: str, + debug_mode: bool, ): ''' Ensure a non-regristar (serving) root actor can spawn a sub and @@ -128,6 +150,8 @@ def test_non_registrar_spawns_child( async def main(): async with tractor.open_nursery( registry_addrs=[reg_addr], + loglevel=loglevel, + debug_mode=debug_mode, ) as an: actor: Actor = tractor.current_actor() @@ -140,7 +164,7 @@ def test_non_registrar_spawns_child( async with sub_ptl.open_context( get_root_portal, ) as (ctx, first): - pass + print('Waiting for `sub` to connect back to us..') await an.cancel()