Add an `actorc` test-driven-dev suite
Defining how an actor-nursery should emit an eg based on non-graceful cancellation in a new `test_actor_nursery` module. Obviously fails atm until the implementation is completed.actor_cancelled_exc_type
							parent
							
								
									2dc13a3304
								
							
						
					
					
						commit
						28d6f77e22
					
				|  | @ -0,0 +1,98 @@ | ||||||
|  | ''' | ||||||
|  | Basic `ActorNursery` operations and closure semantics, | ||||||
|  | - basic remote error collection, | ||||||
|  | - basic multi-subactor cancellation. | ||||||
|  | 
 | ||||||
|  | ''' | ||||||
|  | # import os | ||||||
|  | # import signal | ||||||
|  | # import platform | ||||||
|  | # import time | ||||||
|  | # from itertools import repeat | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | import trio | ||||||
|  | import tractor | ||||||
|  | from tractor._exceptions import ActorCancelled | ||||||
|  | # from tractor._testing import ( | ||||||
|  | #     tractor_test, | ||||||
|  | # ) | ||||||
|  | # from .conftest import no_windows | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.mark.parametrize( | ||||||
|  |     'num_subs', | ||||||
|  |     [ | ||||||
|  |         1, | ||||||
|  |         3, | ||||||
|  |     ] | ||||||
|  | ) | ||||||
|  | def test_one_cancels_all( | ||||||
|  |     start_method: str, | ||||||
|  |     loglevel: str, | ||||||
|  |     debug_mode: bool, | ||||||
|  |     num_subs: int, | ||||||
|  | ): | ||||||
|  |     ''' | ||||||
|  |     Verify that ifa a single error bubbles to the an-scope the | ||||||
|  |     nursery will be cancelled (just like in `trio`); this is a | ||||||
|  |     one-cancels-all style strategy and are only supervision policy | ||||||
|  |     at the moment. | ||||||
|  | 
 | ||||||
|  |     ''' | ||||||
|  |     async def main(): | ||||||
|  |         try: | ||||||
|  |             rte = RuntimeError('Uh oh something bad in parent') | ||||||
|  |             async with tractor.open_nursery( | ||||||
|  |                 start_method=start_method, | ||||||
|  |                 loglevel=loglevel, | ||||||
|  |                 debug_mode=debug_mode, | ||||||
|  |             ) as an: | ||||||
|  | 
 | ||||||
|  |                 # spawn the same number of deamon actors which should be cancelled | ||||||
|  |                 dactor_portals = [] | ||||||
|  |                 for i in range(num_subs): | ||||||
|  |                     name: str= f'sub_{i}' | ||||||
|  |                     ptl: tractor.Portal = await an.start_actor( | ||||||
|  |                         name=name, | ||||||
|  |                         enable_modules=[__name__], | ||||||
|  |                     ) | ||||||
|  |                     dactor_portals.append(ptl) | ||||||
|  | 
 | ||||||
|  |                     # wait for booted | ||||||
|  |                     async with tractor.wait_for_actor(name): | ||||||
|  |                         print(f'{name!r} is up.') | ||||||
|  | 
 | ||||||
|  |                 # simulate uncaught exc | ||||||
|  |                 raise rte | ||||||
|  | 
 | ||||||
|  |             # should error here with a ``RemoteActorError`` or ``MultiError`` | ||||||
|  | 
 | ||||||
|  |         except BaseExceptionGroup as _beg: | ||||||
|  |             beg = _beg | ||||||
|  | 
 | ||||||
|  |             # ?TODO? why can't we do `is` on beg? | ||||||
|  |             assert ( | ||||||
|  |                 beg.exceptions | ||||||
|  |                 == | ||||||
|  |                 an.maybe_error.exceptions | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |             assert len(beg.exceptions) == ( | ||||||
|  |                 num_subs | ||||||
|  |                 + | ||||||
|  |                 1  # rte from root | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |             # all subactors should have been implicitly | ||||||
|  |             # `Portal.cancel_actor()`ed. | ||||||
|  |             excs = list(beg.exceptions) | ||||||
|  |             excs.remove(rte) | ||||||
|  |             for exc in excs: | ||||||
|  |                 assert isinstance(exc, ActorCancelled) | ||||||
|  | 
 | ||||||
|  |             assert an._scope_error is rte | ||||||
|  |             assert not an._children | ||||||
|  |             assert an.cancelled is True | ||||||
|  | 
 | ||||||
|  |     trio.run(main) | ||||||
		Loading…
	
		Reference in New Issue