Add `debugging/subactor_bp_in_ctx.py` test set
It's been in the debug scripts quite a while without a wrapping test and will be, - only the 2nd such REPL test which uses a lower-level `@context` ep-API - the first official and explicit use of `enable_transports=['uds']` a suite. Deats, - flip to 'uds' tpt and 'devx' level logging in the script. - add a new 2-case suite `test_ctxep_pauses_n_maybe_ipc_breaks` which validates both the quit-early (via `BdbQuit`) and channel-dropped-need-to-ctlc cases from a single test fn.enable_tpts
parent
13dbd1d420
commit
df8e326e39
|
@ -33,8 +33,11 @@ async def just_bp(
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
debug_mode=True,
|
debug_mode=True,
|
||||||
|
enable_transports=['uds'],
|
||||||
|
loglevel='devx',
|
||||||
) as n:
|
) as n:
|
||||||
p = await n.start_actor(
|
p = await n.start_actor(
|
||||||
'bp_boi',
|
'bp_boi',
|
||||||
|
|
|
@ -10,10 +10,14 @@ TODO:
|
||||||
- wonder if any of it'll work on OS X?
|
- wonder if any of it'll work on OS X?
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import itertools
|
import itertools
|
||||||
import platform
|
import platform
|
||||||
import time
|
import time
|
||||||
|
from typing import (
|
||||||
|
TYPE_CHECKING,
|
||||||
|
)
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pexpect.exceptions import (
|
from pexpect.exceptions import (
|
||||||
|
@ -34,6 +38,9 @@ from .conftest import (
|
||||||
assert_before,
|
assert_before,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..conftest import PexpectSpawner
|
||||||
|
|
||||||
# TODO: The next great debugger audit could be done by you!
|
# TODO: The next great debugger audit could be done by you!
|
||||||
# - recurrent entry to breakpoint() from single actor *after* and an
|
# - recurrent entry to breakpoint() from single actor *after* and an
|
||||||
# error in another task?
|
# error in another task?
|
||||||
|
@ -1062,6 +1069,88 @@ def test_shield_pause(
|
||||||
child.expect(EOF)
|
child.expect(EOF)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'quit_early', [False, True]
|
||||||
|
)
|
||||||
|
def test_ctxep_pauses_n_maybe_ipc_breaks(
|
||||||
|
spawn: PexpectSpawner,
|
||||||
|
quit_early: bool,
|
||||||
|
):
|
||||||
|
'''
|
||||||
|
Audit generator embedded `.pause()`es from within a `@context`
|
||||||
|
endpoint with a chan close at the end, requiring that ctl-c is
|
||||||
|
mashed and zombie reaper kills sub with no hangs.
|
||||||
|
|
||||||
|
'''
|
||||||
|
child = spawn('subactor_bp_in_ctx')
|
||||||
|
child.expect(PROMPT)
|
||||||
|
|
||||||
|
# 3 iters for the `gen()` pause-points
|
||||||
|
for i in range(3):
|
||||||
|
assert_before(
|
||||||
|
child,
|
||||||
|
[
|
||||||
|
_pause_msg,
|
||||||
|
"('bp_boi'", # actor name
|
||||||
|
"<Task 'just_bp'", # task name
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
i == 1
|
||||||
|
and
|
||||||
|
quit_early
|
||||||
|
):
|
||||||
|
child.sendline('q')
|
||||||
|
child.expect(PROMPT)
|
||||||
|
assert_before(
|
||||||
|
child,
|
||||||
|
["tractor._exceptions.RemoteActorError: remote task raised a 'BdbQuit'",
|
||||||
|
"bdb.BdbQuit",
|
||||||
|
"('bp_boi'",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
child.sendline('c')
|
||||||
|
child.expect(EOF)
|
||||||
|
assert_before(
|
||||||
|
child,
|
||||||
|
["tractor._exceptions.RemoteActorError: remote task raised a 'BdbQuit'",
|
||||||
|
"bdb.BdbQuit",
|
||||||
|
"('bp_boi'",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
break # end-of-test
|
||||||
|
|
||||||
|
child.sendline('c')
|
||||||
|
try:
|
||||||
|
child.expect(PROMPT)
|
||||||
|
except TIMEOUT:
|
||||||
|
# no prompt since we hang due to IPC chan purposely
|
||||||
|
# closed so verify we see error reporting as well as
|
||||||
|
# a failed crash-REPL request msg and can CTL-c our way
|
||||||
|
# out.
|
||||||
|
assert_before(
|
||||||
|
child,
|
||||||
|
['peer IPC channel closed abruptly?',
|
||||||
|
'another task closed this fd',
|
||||||
|
'Debug lock request was CANCELLED?',
|
||||||
|
"TransportClosed: 'MsgpackUDSStream' was already closed locally ?",]
|
||||||
|
|
||||||
|
# XXX races on whether these show/hit?
|
||||||
|
# 'Failed to REPl via `_pause()` You called `tractor.pause()` from an already cancelled scope!',
|
||||||
|
# 'AssertionError',
|
||||||
|
)
|
||||||
|
# OSc(ancel) the hanging tree
|
||||||
|
do_ctlc(
|
||||||
|
child=child,
|
||||||
|
expect_prompt=False,
|
||||||
|
)
|
||||||
|
child.expect(EOF)
|
||||||
|
assert_before(
|
||||||
|
child,
|
||||||
|
['KeyboardInterrupt'],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# TODO: better error for "non-ideal" usage from the root actor.
|
# TODO: better error for "non-ideal" usage from the root actor.
|
||||||
# -[ ] if called from an async scope emit a message that suggests
|
# -[ ] if called from an async scope emit a message that suggests
|
||||||
# using `await tractor.pause()` instead since it's less overhead
|
# using `await tractor.pause()` instead since it's less overhead
|
||||||
|
|
Loading…
Reference in New Issue