Harden `test_debugger` for forkserver spawners
Use `is_forking_spawner` fixture + gate spawner- specific expect patterns in nested-error and daemon tests. Add `set_fork_aware_capture` to multi-sub tests that need capture-mode awareness. Deats, - replace `start_method` param with `is_forking_spawner` bool fixture. - bump inter-send delay to 0.1s for IPC stability under fork backends. - gate `bdb.BdbQuit` + relay-uid patterns behind `not is_forking_spawner` (not visible under capsys). - add `expect(child, EOF)` to confirm clean exit. - switch caught exc from `AssertionError` to `ValueError` in daemon test. (this commit msg was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-codesubint_forkserver_backend
parent
c4885f9d99
commit
9031605807
|
|
@ -356,7 +356,8 @@ def assert_before(
|
||||||
err_on_false=True,
|
err_on_false=True,
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
return str(child.before.decode())
|
before: str = str(child.before.decode())
|
||||||
|
return before
|
||||||
|
|
||||||
|
|
||||||
def do_ctlc(
|
def do_ctlc(
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ from pexpect.exceptions import (
|
||||||
TIMEOUT,
|
TIMEOUT,
|
||||||
EOF,
|
EOF,
|
||||||
)
|
)
|
||||||
|
import tractor
|
||||||
|
|
||||||
from .conftest import (
|
from .conftest import (
|
||||||
do_ctlc,
|
do_ctlc,
|
||||||
|
|
@ -343,6 +344,7 @@ def test_subactor_breakpoint(
|
||||||
def test_multi_subactors(
|
def test_multi_subactors(
|
||||||
spawn,
|
spawn,
|
||||||
ctlc: bool,
|
ctlc: bool,
|
||||||
|
set_fork_aware_capture,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Multiple subactors, both erroring and
|
Multiple subactors, both erroring and
|
||||||
|
|
@ -487,11 +489,12 @@ def test_multi_subactors(
|
||||||
def test_multi_daemon_subactors(
|
def test_multi_daemon_subactors(
|
||||||
spawn,
|
spawn,
|
||||||
loglevel: str,
|
loglevel: str,
|
||||||
ctlc: bool
|
ctlc: bool,
|
||||||
|
set_fork_aware_capture,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Multiple daemon subactors, both erroring and breakpointing within a
|
Multiple daemon subactors, both erroring and breakpointing within
|
||||||
stream.
|
a stream.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
non_linux = _non_linux
|
non_linux = _non_linux
|
||||||
|
|
@ -604,7 +607,10 @@ def test_multi_daemon_subactors(
|
||||||
child,
|
child,
|
||||||
bp_forev_parts,
|
bp_forev_parts,
|
||||||
)
|
)
|
||||||
except AssertionError:
|
except (
|
||||||
|
# AssertionError, # TODO? rm since never raised?
|
||||||
|
ValueError,
|
||||||
|
):
|
||||||
before: str = assert_before(
|
before: str = assert_before(
|
||||||
child,
|
child,
|
||||||
name_error_parts,
|
name_error_parts,
|
||||||
|
|
@ -765,7 +771,8 @@ def test_multi_subactors_root_errors(
|
||||||
def test_multi_nested_subactors_error_through_nurseries(
|
def test_multi_nested_subactors_error_through_nurseries(
|
||||||
ci_env: bool,
|
ci_env: bool,
|
||||||
spawn: PexpectSpawner,
|
spawn: PexpectSpawner,
|
||||||
start_method: str,
|
is_forking_spawner: bool,
|
||||||
|
test_log: tractor.log.StackLevelAdapter,
|
||||||
|
|
||||||
# TODO: address debugger issue for nested tree:
|
# TODO: address debugger issue for nested tree:
|
||||||
# https://github.com/goodboy/tractor/issues/320
|
# https://github.com/goodboy/tractor/issues/320
|
||||||
|
|
@ -786,6 +793,7 @@ def test_multi_nested_subactors_error_through_nurseries(
|
||||||
'multi_nested_subactors_error_up_through_nurseries',
|
'multi_nested_subactors_error_up_through_nurseries',
|
||||||
loglevel='pdb',
|
loglevel='pdb',
|
||||||
)
|
)
|
||||||
|
last_send_char: str|None = None
|
||||||
for (
|
for (
|
||||||
i,
|
i,
|
||||||
send_char,
|
send_char,
|
||||||
|
|
@ -806,11 +814,7 @@ def test_multi_nested_subactors_error_through_nurseries(
|
||||||
|
|
||||||
# XXX forking backends may take longer due to
|
# XXX forking backends may take longer due to
|
||||||
# determinstic IPC cancellation.
|
# determinstic IPC cancellation.
|
||||||
if (
|
if is_forking_spawner:
|
||||||
start_method in [
|
|
||||||
'main_thread_forkserver',
|
|
||||||
]
|
|
||||||
):
|
|
||||||
timeout += 4
|
timeout += 4
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -818,19 +822,26 @@ def test_multi_nested_subactors_error_through_nurseries(
|
||||||
PROMPT,
|
PROMPT,
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
|
delay: float = 0.1
|
||||||
|
test_log.info('Sleeping {delay!r} before next send-chart..')
|
||||||
|
time.sleep(delay)
|
||||||
|
last_send_char: str = send_char
|
||||||
child.sendline(send_char)
|
child.sendline(send_char)
|
||||||
time.sleep(0.01)
|
time.sleep(delay)
|
||||||
|
|
||||||
|
# script finally exited with tb on console.
|
||||||
except EOF:
|
except EOF:
|
||||||
|
test_log.info(
|
||||||
|
f'Breaking from send-char loop'
|
||||||
|
f'last_send_char: {last_send_char!r}\n'
|
||||||
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
assert_before(
|
# boxed source errors
|
||||||
child,
|
expect_patts: list[str] = [
|
||||||
[ # boxed source errors
|
|
||||||
"NameError: name 'doggypants' is not defined",
|
"NameError: name 'doggypants' is not defined",
|
||||||
"tractor._exceptions.RemoteActorError:",
|
"tractor._exceptions.RemoteActorError:",
|
||||||
"('name_error'",
|
"('name_error'",
|
||||||
"bdb.BdbQuit",
|
|
||||||
|
|
||||||
# first level subtrees
|
# first level subtrees
|
||||||
# "tractor._exceptions.RemoteActorError: ('spawner0'",
|
# "tractor._exceptions.RemoteActorError: ('spawner0'",
|
||||||
|
|
@ -844,18 +855,39 @@ def test_multi_nested_subactors_error_through_nurseries(
|
||||||
# "tractor._exceptions.RemoteActorError: ('spawn_until_2'",
|
# "tractor._exceptions.RemoteActorError: ('spawn_until_2'",
|
||||||
# ^-NOTE-^ old RAE repr, new one is below with a field
|
# ^-NOTE-^ old RAE repr, new one is below with a field
|
||||||
# showing the src actor's uid.
|
# showing the src actor's uid.
|
||||||
"src_uid=('spawn_until_0'",
|
|
||||||
"relay_uid=('spawn_until_1'",
|
|
||||||
"src_uid=('spawn_until_2'",
|
"src_uid=('spawn_until_2'",
|
||||||
]
|
]
|
||||||
|
# XXX, I HAVE NO IDEA why these patts only show on the
|
||||||
|
# `trio`-spawner but it seems to have something to do with
|
||||||
|
# what gets dumped in prior-prompt latches somehow??
|
||||||
|
# TODO for claude, explain and or work through how this is
|
||||||
|
# happening but ONLY WHEN RUN FROM THE TEST, bc when i try to
|
||||||
|
# run the test script manually the correct output ALWAYS seems
|
||||||
|
# to be in the last `str(child.before.decode())` output !?!?
|
||||||
|
if (
|
||||||
|
not is_forking_spawner
|
||||||
|
and
|
||||||
|
last_send_char == 'q'
|
||||||
|
):
|
||||||
|
expect_patts += [
|
||||||
|
# expect the pdb-quit exc.
|
||||||
|
"bdb.BdbQuit",
|
||||||
|
# BUT WHY these dude!?
|
||||||
|
"src_uid=('spawn_until_0'",
|
||||||
|
"relay_uid=('spawn_until_1'",
|
||||||
|
]
|
||||||
|
|
||||||
|
assert_before(
|
||||||
|
child,
|
||||||
|
expect_patts,
|
||||||
)
|
)
|
||||||
|
expect(child, EOF)
|
||||||
|
|
||||||
|
|
||||||
# @pytest.mark.timeout(15)
|
# @pytest.mark.timeout(15)
|
||||||
@has_nested_actors
|
@has_nested_actors
|
||||||
def test_root_nursery_cancels_before_child_releases_tty_lock(
|
def test_root_nursery_cancels_before_child_releases_tty_lock(
|
||||||
spawn,
|
spawn,
|
||||||
start_method,
|
|
||||||
ctlc: bool,
|
ctlc: bool,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue