def test_exec_tasks_after_binding(self): "should execute messages to unbound names once bound" name = dramatis.Actor() class O(object): def foo(self,arg): assert arg == "bar" return "foobar" result = [] def block(value): result[:] = [ value ] retval = dramatis.interface( name ).continuation(block).foo("bar") assert retval == None assert result == [] dramatis.Runtime.current.quiesce() assert result == [] dramatis.interface( name ).bind( O() ) dramatis.Runtime.current.quiesce() assert result == [ "foobar" ]
def test_no_double_binding(self): "shouldn't be possible to bind twice" name = dramatis.Actor() dramatis.interface( name ).bind( object() ) okay = False try: dramatis.interface( name ).bind( object() ) raise Exception("should not be reached") except dramatis.error.Bind: okay = True assert okay
def test_bind_with_release(self): "should be possible to bind with a non-rpc continuation" name = dramatis.Actor() result = [] def block(v): result[:] = [ v ] name = dramatis.interface( name ).continuation(block) retval = dramatis.interface( name ).bind( object() ) assert retval == None assert result == [] dramatis.Runtime.current.quiesce() assert result != []
def a(self, other): def result(r): self._block_called = True def exception(e): if str(e) != "hell": raise e self._exception_raised = True ( interface( other ).continuation( { "exception": exception, "result": result } ) ).bb() ( interface( other ).continuation( { "exception": exception, "result": result } ) ).b() other.c()
def a(self, other): def block ( c ): self._block_called = True ( interface( other ).continuation( block ) ).b() other.c()
def __init__(self,name,call_thread): self._state = "start" self._mutex = Lock() self._wait = Condition( self._mutex ) self._call_thread = call_thread self._actor = \ dramatis.interface( Scheduler.actor ).\ _continuation( self, { call_thread: call_thread } )
def __init__(self, name, call_thread, result, exception): # p "p.n #{call_thread} #{result} #{except}" self._result_block = result self._exception_block = exception self._name = name self._continuation = \ dramatis.interface( dramatis.runtime.Scheduler.actor ) \ ._continuation( self, { call_thread: call_thread } )
def test_call_except_blocks(self): "should call exception blocks on exceptions" class a ( dramatis.Actor ): @property def block_called(self): return self._block_called @property def exception_raised(self): return self._exception_raised def __init__(self): self.actor.refuse("c") self.actor.always( "block_called", True ) self.actor.always( "exception_raised", True ) self._block_called = self._exception_raised = False def a(self, other): def result(r): self._block_called = True def exception(e): if str(e) != "hell": raise e self._exception_raised = True ( interface( other ).continuation( { "exception": exception, "result": result } ) ).bb() ( interface( other ).continuation( { "exception": exception, "result": result } ) ).b() other.c() def enable(self): self.actor.default("c") def bb(self): pass def b(self): raise Exception("hell") def c(self): pass a1 = a() a2 = a() ( interface( a1 ).continuation( None ) ).a( a2 ) dramatis.Runtime.current.quiesce() assert not a1.block_called assert a1.exception_raised a2.enable() dramatis.Runtime.current.quiesce() assert a1.block_called
def test_value_if(self): "should have a value interface" class O (object): def foo(self,bar): assert bar == "bar" return 12345 actor = dramatis.Actor(O()) future_name = dramatis.future( actor ) x = future_name.foo("bar") assert isinstance(x,dramatis.Future) x = dramatis.interface( x ).value assert isinstance(x,int) assert x == 12345
def test_block_block_conts_rpc_no_threading( self ): "should block block continuations during an rpc w/o call threading" class a ( dramatis.Actor ): @property def block_called(self): return self._block_called def __init__(self): self._block_called = False self.actor.refuse("c") self.actor.always( "block_called", True ) def a(self, other): def block ( c ): self._block_called = True ( interface( other ).continuation( block ) ).b() other.c() def enable(self): self.actor.default("c") def b(self): pass def c(self): pass a1 = a() a2 = a() ( interface( a1 ).continuation( None ) ).a( a2 ) dramatis.Runtime.current.quiesce() assert not a1.block_called a2.enable() dramatis.Runtime.current.quiesce() assert a1.block_called
def test_allow_exec_blocks(self): "should allow and execute block continuations" class O (object): def foo(self,arg): assert arg == "bar" return "foobar" actor = O() name = dramatis.Actor(actor) result = [] def block(value): result[:] = [value] retval = dramatis.interface( name ).continuation(block).foo( "bar" ) assert retval == None assert result == [] assert result == [] dramatis.Runtime.current.quiesce() assert result == ["foobar"]
def test_refuse(self): "should obey refuse" class a ( dramatis.Actor ): def __init__(self): # warning("REFUSE") self.actor.refuse( "fromB" ) class b ( dramatis.Actor ): def __init__( self, anA ): self._anA = anA def startB( self ): self._anA.fromB() anA = a() aB = b( anA ) ( interface( aB ).continuation( None ) ).startB() dramatis.Runtime.current.warnings = False okay = False try: # warning("before at_exti") dramatis.Runtime.current.at_exit() # warning("after at_exti") raise Exception("should not be reached") except dramatis.error.Uncaught, u: okay = True assert okay dramatis.Runtime.current.warnings = True dramatis.Runtime.reset()
def __radd__(self,that): return that + dramatis.interface(self).value
def __add__(self,that): return dramatis.interface(self).value + that
def exception( self, exception ): try: dramatis.interface( dramatis.release( self._name ) ).exception( exception ) except Exception, e: print_exc() raise e
def test_rpc_binds_return_name(self): "rpc binds should return an actor name" name = dramatis.Actor() retval = dramatis.interface( name ).bind( dict() ) assert isinstance(retval,dramatis.Actor.Name)
def test_block_if_non_threading(self): '''should block calls when in an rpc is inflight and there is no call threading''' class a ( dramatis.Actor ): def __init__( self ): self.actor.refuse( "fromB" ) def _fromB( self ): pass def allow(self): self.actor.default( "fromB" ) self.fromB = self._fromB class b ( dramatis.Actor ): def __init__(self, anA): self._anA = anA self._count = 0 self.actor.always( "count", True ) def startB( self ): self._anA.fromB() @property def count( self ): return self._count def increment(self): self._count += 1 def shouldDeadlock(self): pass anA = a() aB = b(anA) aB_cast = interface( aB ).continuation( None ) assert aB.count == 0 aB.increment() assert aB.count == 1 aB_cast.increment() dramatis.Runtime.current.quiesce() assert aB.count == 2 aB_cast.startB() aB_cast.increment() dramatis.Runtime.current.quiesce() assert aB.count == 2 assert len( dramatis.Runtime.current.exceptions() ) == 0 dramatis.Runtime.current.warnings = False okay = False try: aB.shouldDeadlock() raise Exception("should not be reached") except dramatis.Deadlock: okay = True assert okay okay = False try: dramatis.Runtime.current.quiesce() raise Exception("should not be reached") except dramatis.error.Uncaught: okay = True assert okay dramatis.Runtime.current.warnings = True assert len( dramatis.Runtime.current.exceptions() ) == 2 dramatis.Runtime.current.clear_exceptions() assert len( dramatis.Runtime.current.exceptions() ) == 0 assert aB.count == 2 anA.allow() aB_cast.startB() aB_cast.increment() dramatis.Runtime.current.quiesce() assert aB.count == 3
def test_delv_releases(self): class O (object): def foo(self,arg): assert arg == "bar" name = dramatis.Actor( O() ) dramatis.interface( name ).continuation(None).foo("bar")
def ready(self): # warning( "hi " + str(dramatis.interface( self._future ).ready)) # raise "hell" return dramatis.interface( self._future ).ready
def value(self): return dramatis.interface( self._future ).value
def test_refuse_default(self): "should obey refuse and then recover with default" class a ( dramatis.Actor ): def __init__(self): self.actor.refuse( "fromB" ) def _fromB(self): pass def allow(self): self.actor.default( "fromB" ) self.fromB = self._fromB class b ( dramatis.Actor ): def __init__( self, anA ): self._anA = anA self._count = 0 self.actor.always( "count", True ) def startB( self ): self._anA.fromB() @property def count( self ): # warning( "returning " + str( self._count ) ) return self._count def increment( self ): self._count += 1 return self._count anA = a() aB = b( anA ) aB_cast = interface( aB ).continuation( None ) assert aB.count == 0 aB.increment() assert aB.count == 1 aB_cast.increment() dramatis.Runtime.current.quiesce() assert aB.count == 2 # warning( "a" ) aB_cast.startB() # warning( "b" ) aB_cast.increment() # warning( "c" ) dramatis.Runtime.current.quiesce() # warning( "here " + str(aB.count ) ) assert aB.count == 2 anA.allow() dramatis.Runtime.current.quiesce() assert aB.count == 3