forked from goodboy/tractor
Add a multi-subactor test where the root errors
parent
d43d367153
commit
371025947a
|
@ -0,0 +1,43 @@
|
|||
import tractor
|
||||
|
||||
|
||||
async def name_error():
|
||||
"Raise a ``NameError``"
|
||||
getattr(doggypants)
|
||||
|
||||
|
||||
async def spawn_error():
|
||||
""""A nested nursery that triggers another ``NameError``.
|
||||
"""
|
||||
async with tractor.open_nursery() as n:
|
||||
portal = await n.run_in_actor('name_error_1', name_error)
|
||||
return await portal.result()
|
||||
|
||||
|
||||
async def main():
|
||||
"""The main ``tractor`` routine.
|
||||
|
||||
The process tree should look as approximately as follows:
|
||||
|
||||
-python examples/debugging/multi_subactors.py
|
||||
|-python -m tractor._child --uid ('name_error', 'a7caf490 ...)
|
||||
`-python -m tractor._child --uid ('spawn_error', '52ee14a5 ...)
|
||||
`-python -m tractor._child --uid ('name_error', '3391222c ...)
|
||||
"""
|
||||
async with tractor.open_nursery() as n:
|
||||
|
||||
# spawn both actors
|
||||
portal = await n.run_in_actor('name_error', name_error)
|
||||
portal1 = await n.run_in_actor('spawn_error', spawn_error)
|
||||
|
||||
# trigger a root actor error
|
||||
assert 0
|
||||
|
||||
# attempt to collect results (which raises error in parent)
|
||||
# still has some issues where the parent seems to get stuck
|
||||
await portal.result()
|
||||
await portal1.result()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
tractor.run(main, debug_mode=True)
|
|
@ -35,16 +35,12 @@ async def main():
|
|||
"""
|
||||
async with tractor.open_nursery() as n:
|
||||
|
||||
# spawn both actors
|
||||
portal1 = await n.run_in_actor('bp_forever', breakpoint_forever)
|
||||
portal = await n.run_in_actor('name_error', name_error)
|
||||
portal2 = await n.run_in_actor('spawn_error', spawn_error)
|
||||
|
||||
# attempt to collect results (which raises error in parent)
|
||||
# still has some issues where the parent seems to get stuck
|
||||
# await portal.result()
|
||||
# await portal1.result()
|
||||
# await portal2.result()
|
||||
# Spawn both actors, don't bother with collecting results
|
||||
# (would result in a different debugger outcome due to parent's
|
||||
# cancellation).
|
||||
await n.run_in_actor('bp_forever', breakpoint_forever)
|
||||
await n.run_in_actor('name_error', name_error)
|
||||
await n.run_in_actor('spawn_error', spawn_error)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
"""
|
||||
That native debug better work!
|
||||
|
||||
All these tests can be understood (somewhat) by running the equivalent
|
||||
`examples/debugging/` scripts manually.
|
||||
"""
|
||||
from os import path
|
||||
|
||||
|
@ -10,9 +13,8 @@ from .test_docs_examples import repodir
|
|||
|
||||
|
||||
# TODO:
|
||||
# - recurrent entry from single actor
|
||||
# - recurrent entry to breakpoint() from single actor *after* and an
|
||||
# error
|
||||
# error in another task?
|
||||
# - root error before child errors
|
||||
# - root error after child errors
|
||||
# - root error before child breakpoint
|
||||
|
@ -68,14 +70,14 @@ def test_root_actor_error(spawn, user_in_out):
|
|||
# scan for the pdbpp prompt
|
||||
child.expect(r"\(Pdb\+\+\)")
|
||||
|
||||
before = str(child.before.decode())
|
||||
|
||||
# make sure expected logging and error arrives
|
||||
assert 'TTY lock acquired' in str(child.before)
|
||||
assert 'AssertionError' in str(child.before)
|
||||
assert "Attaching to pdb in crashed actor: ('arbiter'" in before
|
||||
assert 'AssertionError' in before
|
||||
|
||||
# send user command
|
||||
child.sendline(user_input)
|
||||
child.expect('\r\n')
|
||||
child.expect('TTY lock released')
|
||||
|
||||
# process should exit
|
||||
child.expect(pexpect.EOF)
|
||||
|
@ -276,3 +278,35 @@ def test_multi_subactors(spawn):
|
|||
before = str(child.before.decode())
|
||||
assert "RemoteActorError: ('bp_forever'" in before
|
||||
assert 'bdb.BdbQuit' in before
|
||||
|
||||
|
||||
def test_multi_subactors_root_errors(spawn):
|
||||
"""Multiple subactors, both erroring and breakpointing as well as
|
||||
a nested subactor erroring.
|
||||
"""
|
||||
child = spawn('multi_subactor_root_errors')
|
||||
|
||||
# scan for the pdbpp prompt
|
||||
child.expect(r"\(Pdb\+\+\)")
|
||||
|
||||
# at most one subactor should attach before the root is cancelled
|
||||
before = str(child.before.decode())
|
||||
assert "NameError: name 'doggypants' is not defined" in before
|
||||
|
||||
# continue again
|
||||
child.sendline('c')
|
||||
child.expect(r"\(Pdb\+\+\)")
|
||||
|
||||
# should now get attached in root with assert error
|
||||
before = str(child.before.decode())
|
||||
# should have come just after priot prompt
|
||||
assert "Cancelling nursery in ('spawn_error'," in before
|
||||
assert "Attaching to pdb in crashed actor: ('arbiter'" in before
|
||||
assert "AssertionError" in before
|
||||
|
||||
# continue again
|
||||
child.sendline('c')
|
||||
child.expect(pexpect.EOF)
|
||||
|
||||
before = str(child.before.decode())
|
||||
assert "AssertionError" in before
|
||||
|
|
Loading…
Reference in New Issue