Skip to content

Commit

Permalink
Add a multi-subactor test where the root errors
Browse files Browse the repository at this point in the history
  • Loading branch information
goodboy committed Oct 5, 2020
1 parent d43d367 commit 3710259
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 16 deletions.
43 changes: 43 additions & 0 deletions examples/debugging/multi_subactor_root_errors.py
Original file line number Diff line number Diff line change
@@ -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)
16 changes: 6 additions & 10 deletions examples/debugging/multi_subactors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__':
Expand Down
46 changes: 40 additions & 6 deletions tests/test_debugger.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -10,9 +13,8 @@


# 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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

0 comments on commit 3710259

Please sign in to comment.