def testAssociationEqualityWithReconstitutedNonLocalAddress(self): lclAddr = self.am.createLocalAddress() mainAddr1 = ActorAddress(None) mainAddr2 = ActorAddress(9) self.assertNotEqual(mainAddr1, mainAddr2) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr1) self.assertEqual(lclAddr, mainAddr1) self.assertEqual(mainAddr1, lclAddr) self.assertNotEqual(lclAddr, mainAddr2) self.assertNotEqual(mainAddr2, lclAddr) mainAddr1_dup = ActorAddress(None) self.assertEqual(mainAddr1, mainAddr1_dup) self.assertNotEqual(mainAddr1_dup, lclAddr) self.assertEqual(lclAddr, mainAddr1_dup) self.am.importAddr(mainAddr1_dup) self.assertEqual(mainAddr1_dup, lclAddr) self.assertEqual(lclAddr, mainAddr1_dup) self.assertEqual(mainAddr1_dup, mainAddr1)
def test_transmitsCompletingWithCallbackDoNotQueue(self): self.resetCounters() for count in range(MAX_PENDING_TRANSMITS): self.testTrans.scheduleTransmit( None, TransmitIntent(ActorAddress(self), 'message%d' % count, self.successCB, self.failureCB)) self.testTrans.forTestingCompleteAPendingIntent(SendStatus.Sent) self.assertEqual(self.successCBcalls, MAX_PENDING_TRANSMITS) numExtras = len(self.extraTransmitIds) for count in self.extraTransmitIds: self.testTrans.scheduleTransmit( None, TransmitIntent(ActorAddress(self.testTrans), count, self.successCB, self.failureCB)) self.testTrans.forTestingCompleteAPendingIntent(SendStatus.Sent) self.assertEqual(MAX_PENDING_TRANSMITS + numExtras, len(self.testTrans.intents)) self.assertEqual( numExtras, len([ I for I in self.testTrans.intents if I.message in self.extraTransmitIds ]))
def testAssociationHashEqualityWithReconstitutedNonLocalAddress(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr1 = ActorAddress(None) mainAddr2 = ActorAddress(9) assert mainAddr1 != mainAddr2 raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr2) am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr1) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr2) mainAddr1_dup = ActorAddress(None) assert mainAddr1 == mainAddr1_dup raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr1_dup) raises(TypeError, hash, mainAddr2) am.importAddr(mainAddr1_dup) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr1) raises(TypeError, hash, mainAddr1_dup) raises(TypeError, hash, mainAddr2)
def getLocalAddress(self, instanceNum): 'Returns ActorAddress corresponding to local address instance' ra = ActorAddress( ActorLocalAddress(self._thisActorAddr, instanceNum, self)) ra.eqOverride = types.MethodType(self.compareAddressEq, ra) ra.__getstate__ = types.MethodType(_pickle_if_translation, ra) return ra
def test_notification_management(solo_lcs1, solo_lcs2): lcs1, lcs2 = solo_lcs1, solo_lcs2 notifyAddr = ActorAddress('notify') verify_io(lcs1.add_notification_handler(notifyAddr), []) # Re-registration does nothing verify_io(lcs1.add_notification_handler(notifyAddr), []) # Registering a another handler is fine notifyAddr2 = ActorAddress('notify2') verify_io(lcs1.add_notification_handler(notifyAddr2), []) # Re-registration still does nothing verify_io(lcs1.add_notification_handler(notifyAddr), []) # De-registration lcs1.remove_notification_handler(notifyAddr) # Re-registration now adds it back verify_io(lcs1.add_notification_handler(notifyAddr), []) # Multiple de-registration is ok lcs1.remove_notification_handler(notifyAddr) lcs1.remove_notification_handler(notifyAddr) # Re-registration now adds it back again verify_io(lcs1.add_notification_handler(notifyAddr), [])
def testEqualityFailsIfDifferentGeneratingAddress(self): genAddr = ActorAddress(id(self)) genAddr2 = ActorAddress('hi') assert genAddr != genAddr2 addr1 = ActorLocalAddress(genAddr, 0, None) addr2 = ActorLocalAddress(genAddr2, 0, None) assert addr1 != addr2
def testAssociationEqualityWithReconstitutedNonLocalAddress(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr1 = ActorAddress(None) mainAddr2 = ActorAddress(9) assert mainAddr1 != mainAddr2 am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr1) assert lclAddr == mainAddr1 assert mainAddr1 == lclAddr assert lclAddr != mainAddr2 assert mainAddr2 != lclAddr mainAddr1_dup = ActorAddress(None) assert mainAddr1 == mainAddr1_dup assert mainAddr1_dup == lclAddr assert lclAddr == mainAddr1_dup am.importAddr(mainAddr1_dup) assert mainAddr1_dup == lclAddr assert lclAddr == mainAddr1_dup assert mainAddr1_dup == mainAddr1
def testEqualityFailsIfDifferentGeneratingAddress(self): genAddr = ActorAddress(id(self)) genAddr2 = ActorAddress('hi') self.assertNotEqual(genAddr, genAddr2) addr1 = ActorLocalAddress(genAddr, 0, None) addr2 = ActorLocalAddress(genAddr2, 0, None) self.assertNotEqual(addr1, addr2)
def lcs1(): ret = LocalConventionState( ActorAddress(1), { 'Admin Port': 1, 'Convention Address.IPv4': ActorAddress(1), 'popsicle': 'cold' }, StatsManager(), lambda x: ActorAddress(1)) # Activate the system verify_io(ret.setup_convention(activation=True), []) return ret
def test_check_before_activate_with_notifications(lcs1, lcs2): ret = LocalConventionState( ActorAddress(1), { 'Admin Port': 1, 'Convention Address.IPv4': ActorAddress(1), 'popsicle': 'cold' }, StatsManager(), lambda x: ActorAddress(1)) # Activate the system verify_io(ret.setup_convention(), []) notifyAddr = ActorAddress('notify') lcs1.add_notification_handler(notifyAddr) ret = LocalConventionState( ActorAddress(2), { 'Admin Port': 2, 'Convention Address.IPv4': ActorAddress(1), 'apple pie': 'hot' }, StatsManager(), lambda x: ActorAddress(1)) ret._expected_setup_convreg = ConventionRegister(ActorAddress(2), ret.capabilities, firstTime=True, preRegister=False) verify_io(ret.check_convention(), []) # Activate the system verify_io(ret.setup_convention(), [ (ConventionRegister, lambda r, a: (r == ret._expected_setup_convreg and a == ActorAddress(1))), (LogAggregator, None), ])
def testMainAddressRevocation(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) addr = ActorAddress(id(self)) am.deadAddress(addr) assert addr == am.sendToAddress(addr) assert am.isDeadAddress(addr)
def _makeLocalAndAssociated(self, myAddress, am): lclAddr = am.createLocalAddress() mainAddr = ActorAddress(id(lclAddr)) am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) return lclAddr, mainAddr
def test_pendingCallbacksClearQueueAndMoreRunsRunAdditionalQueuedOnMoreCompletions( self): testTrans = FakeTransport() numExtras = len(self.extraTransmitIds) self._extraCompletions(testTrans) # Add more transmits to reach MAX_PENDING_TRANSMITS again for _moreExtras in range(numExtras + 3): testTrans.forTestingCompleteAPendingIntent(SendStatus.Sent) expectedCBCount = 2 * (numExtras + 3) assert self.successCBcalls == expectedCBCount assert MAX_PENDING_TRANSMITS + numExtras == len(testTrans.intents) assert numExtras == len([ I for I in testTrans.intents if I.message in self.extraTransmitIds ]) # Now send more and make sure they are queued for count in self.extraTransmitIds: testTrans.scheduleTransmit( None, TransmitIntent(ActorAddress(3.5), count, self.successCB, self.failureCB)) assert self.successCBcalls == expectedCBCount assert MAX_PENDING_TRANSMITS + 2 * numExtras == len(testTrans.intents) assert 2 * numExtras == len([ I for I in testTrans.intents if I.message in self.extraTransmitIds ]) # And verify that more completions cause the newly Queued to be run for _extras in range(numExtras): testTrans.forTestingCompleteAPendingIntent(SendStatus.Sent) expectedCBCount += numExtras assert self.successCBcalls == expectedCBCount assert (MAX_PENDING_TRANSMITS + numExtras + numExtras) == len( testTrans.intents) assert 2 * numExtras == len([ I for I in testTrans.intents if I.message in self.extraTransmitIds ])
def testMakeAssociation(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(self)) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) # No exception thrown self.assertTrue(True)
def test_prereg_reg_with_notifications(solo_lcs1, solo_lcs2): lcs1, lcs2 = solo_lcs1, solo_lcs2 notifyAddr = ActorAddress('notify') lcs1.add_notification_handler(notifyAddr) lcs1_prereg_2_convreg = ConventionRegister( lcs2.myAddress, {'Admin Port': lcs2.capabilities['Admin Port']}, firstTime=False, preRegister=True) lcs1_to_2_convreg_first = ConventionRegister(lcs1.myAddress, lcs1.capabilities, firstTime=True, preRegister=False) lcs2_to_1_convreg = ConventionRegister(lcs2.myAddress, lcs2.capabilities, firstTime=False, preRegister=False) lcs1_to_2_convreg = ConventionRegister(lcs1.myAddress, lcs1.capabilities, firstTime=False, preRegister=False) verify_io(lcs1.got_convention_register(lcs1_prereg_2_convreg), [ (LostRemote, None), (HysteresisCancel, None), (ConventionRegister, lambda r, a: (r == lcs1_to_2_convreg_first and a == lcs2.myAddress)), ]) # lcs2 gets the ConventionRegister generated above, and responds # with actual info of its own. If the other side is indicating # firstTime, that means it has no previous knowledge; this side # should not also set firstTime or that will bounce back and forth # indefinitely. Note that this side will perform a transport # reset (LostRemote and HysteresisCancel); the TCPTransport may # ignore the transport reset for TXOnly addresses. verify_io(lcs2.got_convention_register(lcs1_to_2_convreg_first), [ (LostRemote, None), (HysteresisCancel, None), (ConventionRegister, lambda r, a: (r == lcs2_to_1_convreg and a == lcs1.myAddress)), ]) # lcs1 gets full ConventionRegister from lcs2. This should also # cause an update notification with the full specification. verify_io(lcs1.got_convention_register(lcs2_to_1_convreg), [ (ConventionRegister, lambda r, a: (r == lcs1_to_2_convreg and a == lcs2.myAddress)), (ActorSystemConventionUpdate, lambda r, a: (r == ActorSystemConventionUpdate(lcs2.myAddress, lcs2.capabilities, added=True) and a == notifyAddr)), ]) verify_normal_notification_updates(lcs1, lcs2)
def test_sendIntentToTransportFailureCallback(self): self.resetCounters() testIntent = TransmitIntent(ActorAddress(None), 'message', self.successCB, self.failureCB) self.testTrans.scheduleTransmit(None, testIntent) self.assertEqual(1, len(self.testTrans.intents)) self.testTrans.forTestingCompleteAPendingIntent(SendStatus.Failed) self.assertEqual(self.successCBcalls, 0) self.assertEqual(self.failureCBcalls, 1)
def testMakeAssociation(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr = ActorAddress(id(self)) am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) # No exception thrown assert True
def _sendAndQueue(self, testTrans): # Initial transmits are all sent directly for count in range(MAX_PENDING_TRANSMITS): testTrans.scheduleTransmit( None, TransmitIntent(ActorAddress('me'), 'message%d' % count, self.successCB, self.failureCB)) assert MAX_PENDING_TRANSMITS == len(testTrans.intents) # After that transmits are queued because none of the previous have completed for count in self.extraTransmitIds: testTrans.scheduleTransmit( None, TransmitIntent(ActorAddress(9), count, self.successCB, self.failureCB)) assert MAX_PENDING_TRANSMITS == len(testTrans.intents) assert not [ I for I in testTrans.intents if I.message in self.extraTransmitIds ]
def test_sendIntentToTransportFailureCallback(self): testTrans = FakeTransport() self.resetCounters() testIntent = TransmitIntent(ActorAddress(None), 'message', self.successCB, self.failureCB) testTrans.scheduleTransmit(None, testIntent) assert 1 == len(testTrans.intents) testTrans.forTestingCompleteAPendingIntent(SendStatus.Failed) assert self.successCBcalls == 0 assert self.failureCBcalls == 1
def lcs2(): ret = LocalConventionState( ActorAddress(2), { 'Admin Port': 2, 'Convention Address.IPv4': ActorAddress(1), 'apple pie': 'hot' }, StatsManager(), lambda x: ActorAddress(1)) ret._expected_setup_convreg = ConventionRegister(ActorAddress(2), ret.capabilities, firstTime=True, preRegister=False) # Activate the system verify_io(ret.setup_convention(activation=True), [ (ConventionRegister, lambda r, a: (r == ret._expected_setup_convreg and a == ActorAddress(1))), (LogAggregator, None), ]) # KWQ: above is a HysteresisSend return ret
def solo_lcs2(): # Like lcs2, but does not specify a convention address; intended # for use with pre-registration (e.g. to simulate TXOnly # environments. ret = LocalConventionState(ActorAddress(2), { 'Admin Port': 2, 'apple pie': 'hot' }, StatsManager(), lambda x: None) # Activate the system assert [] == ret.setup_convention() return ret
def test_sendIntentToTransportUpToLimitAndThenQueueInternally(self): # Initial transmits are all sent directly for count in range(MAX_PENDING_TRANSMITS): self.testTrans.scheduleTransmit( None, TransmitIntent(ActorAddress('me'), 'message%d' % count, self.successCB, self.failureCB)) self.assertEqual(MAX_PENDING_TRANSMITS, len(self.testTrans.intents)) # After that transmits are queued because none of the previous have completed for count in self.extraTransmitIds: self.testTrans.scheduleTransmit( None, TransmitIntent(ActorAddress(9), count, self.successCB, self.failureCB)) self.assertEqual(MAX_PENDING_TRANSMITS, len(self.testTrans.intents)) self.assertFalse([ I for I in self.testTrans.intents if I.message in self.extraTransmitIds ])
def test_reg_with_notifications(lcs1, lcs2): notifyAddr = ActorAddress('notify') lcs1.add_notification_handler(notifyAddr) lcs2_to_1_convreg_first = lcs2._expected_setup_convreg lcs1_to_2_convreg_first = ConventionRegister(lcs1.myAddress, lcs1.capabilities, firstTime=False, preRegister=False) lcs2_to_1_convreg = ConventionRegister(lcs2.myAddress, lcs2.capabilities, firstTime=False, preRegister=False) lcs1_to_2_convreg = ConventionRegister(lcs1.myAddress, lcs1.capabilities, firstTime=False, preRegister=False) verify_io(lcs1.got_convention_register(lcs2_to_1_convreg_first), [ (LostRemote, None), (HysteresisCancel, None), (ConventionRegister, lambda r, a: (r == lcs1_to_2_convreg_first and a == lcs2.myAddress)), (ActorSystemConventionUpdate, lambda r, a: (r == ActorSystemConventionUpdate(lcs2.myAddress, lcs2.capabilities, added=True) and a == notifyAddr)), ]) verify_io(lcs2.got_convention_register(lcs1_to_2_convreg_first), []) # Non-convention leader generates periodic registrations to the # leader (i.e. keepalive) and the leader responds accordingly. verify_io(lcs1.got_convention_register(lcs2_to_1_convreg), [ (ConventionRegister, lambda r, a: (r == lcs1_to_2_convreg and a == lcs2.myAddress)), ]) verify_io(lcs2.got_convention_register(lcs1_to_2_convreg), []) verify_io(lcs1.got_convention_register(lcs2_to_1_convreg), [ (ConventionRegister, lambda r, a: (r == lcs1_to_2_convreg and a == lcs2.myAddress)), ]) verify_io(lcs2.got_convention_register(lcs1_to_2_convreg), []) # Convention check shows all is in order and nothing needs to be done assert [] == lcs1.check_convention() assert [] == lcs2.check_convention() return notifyAddr # used by callers
def testAssociationEquality(self): lclAddr = self.am.createLocalAddress() mainAddr = ActorAddress(id(self)) self.assertNotEqual(lclAddr, mainAddr) self.assertNotEqual(mainAddr, lclAddr) self.am.associateUseableAddress( self.myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) self.assertEqual(lclAddr, mainAddr) self.assertEqual(mainAddr, lclAddr)
def testAssociationEquality(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr = ActorAddress(id(self)) assert lclAddr != mainAddr assert mainAddr != lclAddr am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) assert lclAddr == mainAddr assert mainAddr == lclAddr
def testAssociationStillNotHashable(self): myAddress = 'me' am = ActorAddressManager(None, myAddress) lclAddr = am.createLocalAddress() mainAddr = ActorAddress(id(self)) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr) am.associateUseableAddress(myAddress, lclAddr.addressDetails.addressInstanceNum, mainAddr) raises(TypeError, hash, lclAddr) raises(TypeError, hash, mainAddr)
def test_notification_management_with_registrations(lcs1, lcs2): # Setup both in the registered condition notifyAddr = test_reg_with_notifications(lcs1, lcs2) # Re-registration does nothing verify_io(lcs1.add_notification_handler(notifyAddr), []) # Registering a another handler is fine notifyAddr2 = ActorAddress('notify2') notify_of_lcs2 = ActorSystemConventionUpdate(lcs2.myAddress, lcs2.capabilities, added=True) verify_io(lcs1.add_notification_handler(notifyAddr2), [ (ActorSystemConventionUpdate, lambda r, a: (r == notify_of_lcs2 and a == notifyAddr2)), ]) # Re-registration still does nothing verify_io(lcs1.add_notification_handler(notifyAddr), []) # De-registration lcs1.remove_notification_handler(notifyAddr) # Re-registration now adds it back verify_io(lcs1.add_notification_handler(notifyAddr), [ (ActorSystemConventionUpdate, lambda r, a: (r == notify_of_lcs2 and a == notifyAddr)), ]) # Multiple de-registration is ok lcs1.remove_notification_handler(notifyAddr) lcs1.remove_notification_handler(notifyAddr) # Re-registration now adds it back again verify_io(lcs1.add_notification_handler(notifyAddr), [ (ActorSystemConventionUpdate, lambda r, a: (r == notify_of_lcs2 and a == notifyAddr)), ])
def testGetValidLocalAddress(self): am = ActorAddressManager(None, "I am me") addr = ActorAddress(ActorLocalAddress('I am me', 12, am)) assert isinstance(addr.addressDetails, ActorLocalAddress)
def testInstanceID(self): assert 5 == ActorLocalAddress(ActorAddress(id(self)), 5, None).addressInstanceNum
def testStringForm(self): assert '' != str(ActorLocalAddress(ActorAddress(id(self)), 0, None))
def getLocalAddress(self, instanceNum): 'Returns ActorAddress corresponding to local address instance' ra = ActorAddress(ActorLocalAddress(self._thisActorAddr, instanceNum, self)) ra.eqOverride = types.MethodType(self.compareAddressEq, ra) ra.__getstate__ = types.MethodType(_pickle_if_translation, ra) return ra