Example #1
0
 def testNonLocalAddressRevocationAssociation(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     lclAddr, mainAddr = self._makeLocalAndAssociated(myAddress, am)
     am.deadAddress(mainAddr)
     assert mainAddr == am.sendToAddress(lclAddr)
     assert mainAddr == am.sendToAddress(mainAddr)
     assert am.isDeadAddress(lclAddr)
     assert am.isDeadAddress(mainAddr)
     assert am.isDeadAddress(am.sendToAddress(mainAddr))
     assert am.isDeadAddress(am.sendToAddress(lclAddr))
Example #2
0
 def testNonLocalAddressRevocationAssociation(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     lclAddr, mainAddr = self._makeLocalAndAssociated(myAddress, am)
     am.deadAddress(mainAddr)
     assert mainAddr == am.sendToAddress(lclAddr)
     assert mainAddr == am.sendToAddress(mainAddr)
     assert am.isDeadAddress(lclAddr)
     assert am.isDeadAddress(mainAddr)
     assert am.isDeadAddress(am.sendToAddress(mainAddr))
     assert am.isDeadAddress(am.sendToAddress(lclAddr))
class TestLocalAddresses(unittest.TestCase):
    scope='unit'

    def setUp(self):
        self.myAddress = 'me'
        self.am = ActorAddressManager(None, self.myAddress)

    def testGetValidLocalAddress(self):
        addr = ActorAddress(ActorLocalAddress(self.myAddress, 12, self.am))
        self.assertIsInstance(addr.addressDetails, ActorLocalAddress)

    def testGetUniqueLocalAddresses(self):
        addr1 = self.am.createLocalAddress()
        addr2 = self.am.createLocalAddress()
        self.assertNotEqual(addr1, addr2)
        self.assertNotEqual(addr2, addr1)
        self.assertEqual(addr1, addr1)
        self.assertEqual(addr2, addr2)

    def testLocalAddressCannotBePickled(self):
        self.am = ActorAddressManager(None, 'me')
        addr = self.am.createLocalAddress()
        self.assertRaises(CannotPickleAddress, pickle.dumps, addr)

    def testLocalAddressCanBeReconstituted(self):
        addr = self.am.createLocalAddress()
        addr2 = self.am.getLocalAddress(addr.addressDetails.addressInstanceNum)
        self.assertEqual(addr, addr2)

    def testLocalAddressCannotBeUsedForSending(self):
        addr = self.am.createLocalAddress()
        self.assertIsNone(self.am.sendToAddress(addr))
Example #4
0
 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)
Example #5
0
 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)
Example #6
0
class TestLocalAddresses(unittest.TestCase):
    scope = 'unit'

    def setUp(self):
        self.myAddress = 'me'
        self.am = ActorAddressManager(None, self.myAddress)

    def testGetValidLocalAddress(self):
        addr = ActorAddress(ActorLocalAddress(self.myAddress, 12, self.am))
        self.assertIsInstance(addr.addressDetails, ActorLocalAddress)

    def testGetUniqueLocalAddresses(self):
        addr1 = self.am.createLocalAddress()
        addr2 = self.am.createLocalAddress()
        self.assertNotEqual(addr1, addr2)
        self.assertNotEqual(addr2, addr1)
        self.assertEqual(addr1, addr1)
        self.assertEqual(addr2, addr2)

    def testLocalAddressCannotBePickled(self):
        self.am = ActorAddressManager(None, 'me')
        addr = self.am.createLocalAddress()
        self.assertRaises(CannotPickleAddress, pickle.dumps, addr)

    def testLocalAddressCanBeReconstituted(self):
        addr = self.am.createLocalAddress()
        addr2 = self.am.getLocalAddress(addr.addressDetails.addressInstanceNum)
        self.assertEqual(addr, addr2)

    def testLocalAddressCannotBeUsedForSending(self):
        addr = self.am.createLocalAddress()
        self.assertIsNone(self.am.sendToAddress(addr))
Example #7
0
 def testLocalAddressRevocation(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     lcladdr = am.createLocalAddress()
     am.deadAddress(lcladdr)
     assert am.sendToAddress(lcladdr) is None
     assert am.isDeadAddress(lcladdr)
     assert lcladdr == am.getLocalAddress(
         lcladdr.addressDetails.addressInstanceNum)
Example #8
0
 def testLocalAddressRevocation(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     lcladdr = am.createLocalAddress()
     am.deadAddress(lcladdr)
     assert am.sendToAddress(lcladdr) is None
     assert am.isDeadAddress(lcladdr)
     assert lcladdr == am.getLocalAddress(
         lcladdr.addressDetails.addressInstanceNum)
Example #9
0
 def testAssociationRemembered(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     lclAddr, mainAddr = self._makeLocalAndAssociated(myAddress, am)
     assert mainAddr == am.sendToAddress(lclAddr)
     assert mainAddr == am.sendToAddress(mainAddr)
Example #10
0
 def testLocalAddressCannotBeUsedForSending(self):
     am = ActorAddressManager(None, "here")
     addr = am.createLocalAddress()
     assert am.sendToAddress(addr) is None
Example #11
0
class systemCommonBase(object):
    def __init__(self, adminAddr, transport):
        self._adminAddr = adminAddr
        self.transport = transport
        self._addrManager = ActorAddressManager(adminAddr,
                                                self.transport.myAddress)
        self.transport.setAddressManager(self._addrManager)
        self._finalTransmitPending = {
        }  # key = target ActorAddress, value=None or the last pending Intent
        self._awaitingAddressUpdate = {
        }  # key = actorAddress waited on (usually local), value=array of transmit Intents
        self._receiveQueue = []  # array of ReceiveMessage to be processed
        self._children = [
        ]  # array of Addresses of children of this Actor/Admin
        self._governer = RateThrottle(RATE_THROTTLE)
        self._sCBStats = StatsManager()

    @property
    def address(self):
        return self.transport.myAddress

    @property
    def myAddress(self):
        return self.transport.myAddress

    @property
    def childAddresses(self):
        return self._children

    def _registerChild(self, childAddress):
        self._children.append(childAddress)

    def _handleChildExited(self, childAddress):
        self._sCBStats.inc('Common.Message Received.Child Actor Exited')
        self._addrManager.deadAddress(childAddress)
        self.transport.deadAddress(self._addrManager, childAddress)
        self._childExited(childAddress)
        self._children = [C for C in self._children if C != childAddress]
        if hasattr(self, '_exiting') and not self._children:
            # OK, all children are dead, can now exit this actor, but
            # make sure this final cleanup only occurs once
            # (e.g. transport.deadAddress above could recurse through
            # here as well.
            if not hasattr(self, '_exitedAlready'):
                self._exitedAlready = True
                self._sayGoodbye()
                self.transport.abort_run(drain=True)
        return True

    def _updateStatusResponse(self, resp):
        "Called to update a Thespian_SystemStatus or Thespian_ActorStatus with common information"
        for each in self.childAddresses:
            resp.addChild(each)
        for each in self._receiveQueue:
            resp.addReceivedMessage(each.sender, self.myAddress, each.message)
        self._sCBStats.copyToStatusResponse(resp)
        # Need to show _finalTransmitPending?  where is head of chain? shown by transport? (no)
        resp.governer = str(self._governer)
        for addr in self._awaitingAddressUpdate:
            resp.addTXPendingAddressCount(
                addr, len(self._awaitingAddressUpdate[addr]))
        self.transport._updateStatusResponse(resp)

    def setLoggingControls(self, envelope):
        from thespian.system.utilis import thesplog_control
        msg = envelope.message
        thesplog_control(msg.threshold, msg.useLogging, msg.useFile)
        return True

    # ----------------------------------------------------------------------
    # Transmit management

    def _send_intent(self, intent):
        self._governer.eventRatePause()
        # Check if there are any existing transmits in progress to
        # this address (on either the input address or the validated
        # address); if so, just add the new one to the list and
        # return.
        sendAddr = self._addrManager.sendToAddress(intent.targetAddr)
        finalIntent = self._finalTransmitPending.get(
            intent.targetAddr, self._finalTransmitPending.get(sendAddr, None))
        self._finalTransmitPending[sendAddr or intent.targetAddr] = intent
        if finalIntent:
            finalIntent.nextIntent = intent
            self._sCBStats.inc('Actor.Message Send.Added to End of Sends')
            return
        self._send_intent_to_transport(intent)

    def _retryPendingChildOperations(self, childInstance, actualAddress):
        # actualAddress will be none if the child could not be created
        lcladdr = self._addrManager.getLocalAddress(childInstance)

        if not actualAddress:
            self._receiveQueue.append(
                ReceiveEnvelope(lcladdr, ChildActorExited(lcladdr)))

        if lcladdr in self._finalTransmitPending:
            # KWQ: what to do when actualAddress is None?
            self._finalTransmitPending[
                actualAddress] = self._finalTransmitPending[lcladdr]
            del self._finalTransmitPending[lcladdr]

        if lcladdr in self._awaitingAddressUpdate:
            pending = self._awaitingAddressUpdate[lcladdr]
            del self._awaitingAddressUpdate[lcladdr]
            for each in pending:
                if actualAddress:
                    # KWQ: confirm the following two lines can be removed; send_intent_to_transport should do this translation on its own.  At that point, the changeTargetAddr method should be able to be removed.
                    #                if each.targetAddr == lcladdr:
                    #                    each.changeTargetAddr(actualAddress)
                    self._sCBStats.inc(
                        'Actor.Message Send.Transmit ReInitiated')
                    self._send_intent(each)
                else:
                    if not isinstance(each.message, PoisonMessage):
                        self._receiveQueue.append(
                            ReceiveEnvelope(self.myAddress,
                                            PoisonMessage(each.message)))
                    self._sCBStats.inc(
                        'Actor.Message Send.Poison Return on Child Abort')
                    each.result = SendStatus.Failed
                    each.completionCallback()

    def _send_intent_to_transport(self, intent):
        thesplog('Attempting intent %s',
                 intent.identify(),
                 level=logging.DEBUG)
        if not hasattr(intent, '_addedCheckNextTransmitCB'):
            intent.addCallback(self._checkNextTransmit,
                               self._checkNextTransmit)
            # Protection against duplicate callback additions in case
            # of a retry due to the CannotPickleAddress exception below.
            intent._addedCheckNextTransmitCB = True
        try:
            self.transport.scheduleTransmit(self._addrManager, intent)
            self._sCBStats.inc('Actor.Message Send.Transmit Started')
        except CannotPickleAddress as ex:
            thesplog('CannotPickleAddress, appending intent for %s (hash=%s)',
                     ex.address,
                     hash(ex.address),
                     level=logging.DEBUG)
            self._awaitingAddressUpdate.setdefault(ex.address,
                                                   []).append(intent)
            self._sCBStats.inc('Actor.Message Send.Postponed for Address')
            self._checkNextTransmit(0, intent)
        except Exception:
            import traceback
            thesplog('Declaring transmit of %s as Poison: %s',
                     intent.identify(),
                     traceback.format_exc(),
                     exc_info=True,
                     level=logging.ERROR)
            if not isinstance(intent.message, PoisonMessage):
                self._receiveQueue.append(
                    ReceiveEnvelope(intent.targetAddr,
                                    PoisonMessage(intent.message)))
            self._sCBStats.inc('Actor.Message Send.Transmit Poison Rejection')
            intent.result = SendStatus.Failed
            intent.completionCallback()

    def _checkNextTransmit(self, result, completedIntent):
        # This is the callback for (all) TransmitIntents that will
        # send the next queued intent for that destination.
        if completedIntent.nextIntent:
            self._send_intent_to_transport(completedIntent.nextIntent)
        else:
            fkey = completedIntent.targetAddr
            if fkey not in self._finalTransmitPending:
                fkey = self._addrManager.sendToAddress(
                    completedIntent.targetAddr)
                if fkey not in self._finalTransmitPending:
                    if isinstance(completedIntent.message, DeadEnvelope):
                        fkey = completedIntent.message.deadAddress
                        if fkey not in self._finalTransmitPending:
                            fkey = self._addrManager.sendToAddress(fkey)

            if fkey in self._finalTransmitPending:
                if self._finalTransmitPending[fkey] != completedIntent:
                    thesplog(
                        'Completed final intent %s does not match recorded final intent: %s',
                        completedIntent.identify(),
                        self._finalTransmitPending[fkey].identify(),
                        level=logging.WARNING)
                del self._finalTransmitPending[fkey]
            else:
                thesplog(
                    'Completed Transmit Intent %s for unrecorded destination %s / %s in %s',
                    completedIntent.identify(),
                    str(
                        self._addrManager.sendToAddress(
                            completedIntent.targetAddr)),
                    fkey,
                    str(map(str, self._finalTransmitPending.keys())),
                    level=logging.WARNING)
                self._sCBStats.inc('Action.Message Send.Unknown Completion')
                return
Example #12
0
class TestAddressManagerAddressRevocation(unittest.TestCase):
    scope = 'unit'

    def setUp(self):
        self.myAddress = 'me'
        self.am = ActorAddressManager(None, self.myAddress)

    def _makeLocalAndAssociated(self):
        lclAddr = self.am.createLocalAddress()
        mainAddr = ActorAddress(id(lclAddr))
        self.am.associateUseableAddress(
            self.myAddress, lclAddr.addressDetails.addressInstanceNum,
            mainAddr)
        return lclAddr, mainAddr

    def testLocalAddressRevocation(self):
        lcladdr = self.am.createLocalAddress()
        self.am.deadAddress(lcladdr)
        self.assertIsNone(self.am.sendToAddress(lcladdr))
        self.assertTrue(self.am.isDeadAddress(lcladdr))
        self.assertEqual(
            lcladdr,
            self.am.getLocalAddress(lcladdr.addressDetails.addressInstanceNum))

    def testMainAddressRevocation(self):
        addr = ActorAddress(id(self))
        self.am.deadAddress(addr)
        self.assertEqual(addr, self.am.sendToAddress(addr))
        self.assertTrue(self.am.isDeadAddress(addr))

    def testLocalAddressRevocationAssociation(self):
        lclAddr, mainAddr = self._makeLocalAndAssociated()
        self.am.deadAddress(lclAddr)
        self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr))
        self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(lclAddr))
        self.assertTrue(self.am.isDeadAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr)))

    def testNonLocalAddressRevocationAssociation(self):
        lclAddr, mainAddr = self._makeLocalAndAssociated()
        self.am.deadAddress(mainAddr)
        self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr))
        self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(lclAddr))
        self.assertTrue(self.am.isDeadAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr)))

    def testAssociatedAddressRevocationIsUnique(self):
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated()
        lclAddr2, mainAddr2 = self._makeLocalAndAssociated()
        lclAddr3, mainAddr3 = self._makeLocalAndAssociated()

        self.assertFalse(self.am.isDeadAddress(lclAddr1))
        self.assertFalse(self.am.isDeadAddress(mainAddr1))
        self.assertFalse(
            self.am.isDeadAddress(self.am.sendToAddress(mainAddr1)))
        self.assertFalse(self.am.isDeadAddress(
            self.am.sendToAddress(lclAddr1)))

        self.assertFalse(self.am.isDeadAddress(lclAddr2))
        self.assertFalse(self.am.isDeadAddress(mainAddr2))
        self.assertFalse(
            self.am.isDeadAddress(self.am.sendToAddress(mainAddr2)))
        self.assertFalse(self.am.isDeadAddress(
            self.am.sendToAddress(lclAddr2)))

        self.assertFalse(self.am.isDeadAddress(lclAddr3))
        self.assertFalse(self.am.isDeadAddress(mainAddr3))
        self.assertFalse(
            self.am.isDeadAddress(self.am.sendToAddress(mainAddr3)))
        self.assertFalse(self.am.isDeadAddress(
            self.am.sendToAddress(lclAddr3)))

        self.am.deadAddress(lclAddr1)
        self.am.deadAddress(mainAddr2)

        self.assertTrue(self.am.isDeadAddress(lclAddr1))
        self.assertTrue(self.am.isDeadAddress(mainAddr1))
        self.assertTrue(self.am.isDeadAddress(
            self.am.sendToAddress(mainAddr1)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr1)))

        self.assertTrue(self.am.isDeadAddress(lclAddr2))
        self.assertTrue(self.am.isDeadAddress(mainAddr2))
        self.assertTrue(self.am.isDeadAddress(
            self.am.sendToAddress(mainAddr2)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr2)))

        self.assertFalse(self.am.isDeadAddress(lclAddr3))
        self.assertFalse(self.am.isDeadAddress(mainAddr3))
        self.assertFalse(
            self.am.isDeadAddress(self.am.sendToAddress(mainAddr3)))
        self.assertFalse(self.am.isDeadAddress(
            self.am.sendToAddress(lclAddr3)))
class TestAddressManagerAddressRevocation(unittest.TestCase):
    scope='unit'

    def setUp(self):
        self.myAddress = 'me'
        self.am = ActorAddressManager(None, self.myAddress)

    def _makeLocalAndAssociated(self):
        lclAddr = self.am.createLocalAddress()
        mainAddr = ActorAddress(id(lclAddr))
        self.am.associateUseableAddress(self.myAddress,
                                        lclAddr.addressDetails.addressInstanceNum,
                                        mainAddr)
        return lclAddr, mainAddr

    def testLocalAddressRevocation(self):
        lcladdr = self.am.createLocalAddress()
        self.am.deadAddress(lcladdr)
        self.assertIsNone(self.am.sendToAddress(lcladdr))
        self.assertTrue(self.am.isDeadAddress(lcladdr))
        self.assertEqual(lcladdr,
                         self.am.getLocalAddress(lcladdr.addressDetails.addressInstanceNum))

    def testMainAddressRevocation(self):
        addr = ActorAddress(id(self))
        self.am.deadAddress(addr)
        self.assertEqual(addr, self.am.sendToAddress(addr))
        self.assertTrue(self.am.isDeadAddress(addr))

    def testLocalAddressRevocationAssociation(self):
        lclAddr, mainAddr = self._makeLocalAndAssociated()
        self.am.deadAddress(lclAddr)
        self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr))
        self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(lclAddr))
        self.assertTrue(self.am.isDeadAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr)))

    def testNonLocalAddressRevocationAssociation(self):
        lclAddr, mainAddr = self._makeLocalAndAssociated()
        self.am.deadAddress(mainAddr)
        self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr))
        self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(lclAddr))
        self.assertTrue(self.am.isDeadAddress(mainAddr))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr)))

    def testAssociatedAddressRevocationIsUnique(self):
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated()
        lclAddr2, mainAddr2 = self._makeLocalAndAssociated()
        lclAddr3, mainAddr3 = self._makeLocalAndAssociated()

        self.assertFalse(self.am.isDeadAddress(lclAddr1))
        self.assertFalse(self.am.isDeadAddress(mainAddr1))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr1)))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr1)))

        self.assertFalse(self.am.isDeadAddress(lclAddr2))
        self.assertFalse(self.am.isDeadAddress(mainAddr2))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr2)))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr2)))

        self.assertFalse(self.am.isDeadAddress(lclAddr3))
        self.assertFalse(self.am.isDeadAddress(mainAddr3))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr3)))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr3)))

        self.am.deadAddress(lclAddr1)
        self.am.deadAddress(mainAddr2)

        self.assertTrue(self.am.isDeadAddress(lclAddr1))
        self.assertTrue(self.am.isDeadAddress(mainAddr1))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr1)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr1)))

        self.assertTrue(self.am.isDeadAddress(lclAddr2))
        self.assertTrue(self.am.isDeadAddress(mainAddr2))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(mainAddr2)))
        self.assertTrue(self.am.isDeadAddress(self.am.sendToAddress(lclAddr2)))

        self.assertFalse(self.am.isDeadAddress(lclAddr3))
        self.assertFalse(self.am.isDeadAddress(mainAddr3))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(mainAddr3)))
        self.assertFalse(self.am.isDeadAddress(self.am.sendToAddress(lclAddr3)))
Example #14
0
 def testLocalAddressCannotBeUsedForSending(self):
     am = ActorAddressManager(None, "here")
     addr = am.createLocalAddress()
     assert am.sendToAddress(addr) is None
Example #15
0
 def testAssociationUnique(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     self.testAssociationRemembered()
     lclAddr2 = am.createLocalAddress()
     assert am.sendToAddress(lclAddr2) is None
Example #16
0
 def testAssociationNotRequiredForUseableNonLocal(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     addr = ActorAddress(id(self))
     assert addr == am.sendToAddress(addr)
Example #17
0
 def testAssociationUnique(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     self.testAssociationRemembered()
     lclAddr2 = am.createLocalAddress()
     assert am.sendToAddress(lclAddr2) is None
Example #18
0
 def testAssociationRemembered(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     lclAddr, mainAddr = self._makeLocalAndAssociated(myAddress, am)
     assert mainAddr == am.sendToAddress(lclAddr)
     assert mainAddr == am.sendToAddress(mainAddr)
Example #19
0
 def testAssociationNotRequiredForUseableNonLocal(self):
     myAddress = 'me'
     am = ActorAddressManager(None, myAddress)
     addr = ActorAddress(id(self))
     assert addr == am.sendToAddress(addr)
Example #20
0
    def testAssociatedAddressRevocationIsUnique(self):
        myAddress = 'me'
        am = ActorAddressManager(None, myAddress)
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated(myAddress, am)
        print('1',str(lclAddr1),str(mainAddr1))
        lclAddr2, mainAddr2 = self._makeLocalAndAssociated(myAddress, am)
        print('2',str(lclAddr2),str(mainAddr2))
        lclAddr3, mainAddr3 = self._makeLocalAndAssociated(myAddress, am)
        print('3',str(lclAddr3),str(mainAddr3))

        assert not am.isDeadAddress(lclAddr1)
        assert not am.isDeadAddress(mainAddr1)
        print('1sm',str(am.sendToAddress(mainAddr1)))
        assert not am.isDeadAddress(am.sendToAddress(mainAddr1))
        print('1sl',str(am.sendToAddress(lclAddr1)))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr1))

        assert not am.isDeadAddress(lclAddr2)
        assert not am.isDeadAddress(mainAddr2)
        assert not am.isDeadAddress(am.sendToAddress(mainAddr2))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr2))

        assert not am.isDeadAddress(lclAddr3)
        assert not am.isDeadAddress(mainAddr3)
        assert not am.isDeadAddress(am.sendToAddress(mainAddr3))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr3))

        am.deadAddress(lclAddr1)
        am.deadAddress(mainAddr2)

        assert am.isDeadAddress(lclAddr1)
        assert am.isDeadAddress(mainAddr1)
        assert am.isDeadAddress(am.sendToAddress(mainAddr1))
        assert am.isDeadAddress(am.sendToAddress(lclAddr1))

        assert am.isDeadAddress(lclAddr2)
        assert am.isDeadAddress(mainAddr2)
        assert am.isDeadAddress(am.sendToAddress(mainAddr2))
        assert am.isDeadAddress(am.sendToAddress(lclAddr2))

        assert not am.isDeadAddress(lclAddr3)
        assert not am.isDeadAddress(mainAddr3)
        assert not am.isDeadAddress(am.sendToAddress(mainAddr3))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr3))
Example #21
0
class systemCommonBase(object):

    def __init__(self, adminAddr, transport):
        self._adminAddr   = adminAddr
        self.transport    = transport
        self._addrManager = ActorAddressManager(adminAddr, self.transport.myAddress)
        self.transport.setAddressManager(self._addrManager)
        self._finalTransmitPending = {} # key = target ActorAddress, value=None or the last pending Intent
        self._awaitingAddressUpdate = {}  # key = actorAddress waited on (usually local), value=array of transmit Intents
        self._receiveQueue = []  # array of ReceiveMessage to be processed
        self._children = []  # array of Addresses of children of this Actor/Admin
        self._governer = RateThrottle(RATE_THROTTLE)
        self._sCBStats = StatsManager()


    @property
    def address(self): return self.transport.myAddress
    @property
    def myAddress(self): return self.transport.myAddress


    @property
    def childAddresses(self): return self._children

    def _registerChild(self, childAddress): self._children.append(childAddress)

    def _handleChildExited(self, childAddress):
        self._sCBStats.inc('Common.Message Received.Child Actor Exited')
        self._addrManager.deadAddress(childAddress)
        self.transport.deadAddress(self._addrManager, childAddress)
        self._childExited(childAddress)
        self._children = [C for C in self._children if C != childAddress]
        if hasattr(self, '_exiting') and not self._children:
            # OK, all children are dead, can now exit this actor, but
            # make sure this final cleanup only occurs once
            # (e.g. transport.deadAddress above could recurse through
            # here as well.
            if not hasattr(self, '_exitedAlready'):
                self._exitedAlready = True
                self._sayGoodbye()
                self.transport.abort_run(drain=True)
        return True


    def _updateStatusResponse(self, resp):
        "Called to update a Thespian_SystemStatus or Thespian_ActorStatus with common information"
        for each in self.childAddresses:
            resp.addChild(each)
        for each in self._receiveQueue:
            resp.addReceivedMessage(each.sender, self.myAddress, each.message)
        self._sCBStats.copyToStatusResponse(resp)
        # Need to show _finalTransmitPending?  where is head of chain? shown by transport? (no)
        resp.governer = str(self._governer)
        for addr in self._awaitingAddressUpdate:
            resp.addTXPendingAddressCount(addr, len(self._awaitingAddressUpdate[addr]))
        self.transport._updateStatusResponse(resp)


    def setLoggingControls(self, envelope):
        from thespian.system.utilis import thesplog_control
        msg = envelope.message
        thesplog_control(msg.threshold, msg.useLogging, msg.useFile)
        return True


    # ----------------------------------------------------------------------
    # Transmit management

    def _send_intent(self, intent):
        self._governer.eventRatePause()
        # Check if there are any existing transmits in progress to
        # this address (on either the input address or the validated
        # address); if so, just add the new one to the list and
        # return.
        sendAddr = self._addrManager.sendToAddress(intent.targetAddr)
        finalIntent = self._finalTransmitPending.get(
            intent.targetAddr,
            self._finalTransmitPending.get(sendAddr, None))
        self._finalTransmitPending[sendAddr or intent.targetAddr] = intent
        if finalIntent:
            finalIntent.nextIntent = intent
            self._sCBStats.inc('Actor.Message Send.Added to End of Sends')
            return
        self._send_intent_to_transport(intent)


    def _retryPendingChildOperations(self, childInstance, actualAddress):
        # actualAddress will be none if the child could not be created
        lcladdr = self._addrManager.getLocalAddress(childInstance)

        if not actualAddress:
            self._receiveQueue.append(ReceiveEnvelope(lcladdr, ChildActorExited(lcladdr)))

        if lcladdr in self._finalTransmitPending:
            # KWQ: what to do when actualAddress is None?
            self._finalTransmitPending[actualAddress] = self._finalTransmitPending[lcladdr]
            del self._finalTransmitPending[lcladdr]

        if lcladdr in self._awaitingAddressUpdate:
            pending = self._awaitingAddressUpdate[lcladdr]
            del self._awaitingAddressUpdate[lcladdr]
            for each in pending:
                if actualAddress:
                    # KWQ: confirm the following two lines can be removed; send_intent_to_transport should do this translation on its own.  At that point, the changeTargetAddr method should be able to be removed.
    #                if each.targetAddr == lcladdr:
    #                    each.changeTargetAddr(actualAddress)
                    self._sCBStats.inc('Actor.Message Send.Transmit ReInitiated')
                    self._send_intent(each)
                else:
                    if not isinstance(each.message, PoisonMessage):
                        self._receiveQueue.append(
                            ReceiveEnvelope(self.myAddress,
                                            PoisonMessage(each.message)))
                    self._sCBStats.inc('Actor.Message Send.Poison Return on Child Abort')
                    each.result = SendStatus.Failed
                    each.completionCallback()


    def _send_intent_to_transport(self, intent):
        thesplog('Attempting intent %s', intent.identify(), level=logging.DEBUG)
        if not hasattr(intent, '_addedCheckNextTransmitCB'):
            intent.addCallback(self._checkNextTransmit, self._checkNextTransmit)
            # Protection against duplicate callback additions in case
            # of a retry due to the CannotPickleAddress exception below.
            intent._addedCheckNextTransmitCB = True
        try:
            self.transport.scheduleTransmit(self._addrManager, intent)
            self._sCBStats.inc('Actor.Message Send.Transmit Started')
        except CannotPickleAddress as ex:
            thesplog('CannotPickleAddress, appending intent for %s (hash=%s)',
                     ex.address, hash(ex.address), level=logging.DEBUG)
            self._awaitingAddressUpdate.setdefault(ex.address, []).append(intent)
            self._sCBStats.inc('Actor.Message Send.Postponed for Address')
            self._checkNextTransmit(0, intent)
        except Exception:
            import traceback
            thesplog('Declaring transmit of %s as Poison: %s', intent.identify(),
                     traceback.format_exc(), exc_info=True, level=logging.ERROR)
            if not isinstance(intent.message, PoisonMessage):
                self._receiveQueue.append(ReceiveEnvelope(intent.targetAddr, PoisonMessage(intent.message)))
            self._sCBStats.inc('Actor.Message Send.Transmit Poison Rejection')
            intent.result = SendStatus.Failed
            intent.completionCallback()


    def _checkNextTransmit(self, result, completedIntent):
        # This is the callback for (all) TransmitIntents that will
        # send the next queued intent for that destination.
        if completedIntent.nextIntent:
            self._send_intent_to_transport(completedIntent.nextIntent)
        else:
            fkey = completedIntent.targetAddr
            if fkey not in self._finalTransmitPending:
                fkey = self._addrManager.sendToAddress(completedIntent.targetAddr)
                if fkey not in self._finalTransmitPending:
                    if isinstance(completedIntent.message, DeadEnvelope):
                        fkey = completedIntent.message.deadAddress
                        if fkey not in self._finalTransmitPending:
                            fkey = self._addrManager.sendToAddress(fkey)

            if fkey in self._finalTransmitPending:
                if self._finalTransmitPending[fkey] != completedIntent:
                    thesplog('Completed final intent %s does not match recorded final intent: %s',
                             completedIntent.identify(),
                             self._finalTransmitPending[fkey].identify(),
                             level=logging.WARNING)
                del self._finalTransmitPending[fkey]
            else:
                thesplog('Completed Transmit Intent %s for unrecorded destination %s / %s in %s',
                         completedIntent.identify(),
                         str(self._addrManager.sendToAddress(completedIntent.targetAddr)),
                         fkey,
                         str(map(str,self._finalTransmitPending.keys())),
                         level=logging.WARNING)
                self._sCBStats.inc('Action.Message Send.Unknown Completion')
                return
Example #22
0
class TestAddressManagerLocalAddressAssociations(unittest.TestCase):
    scope = 'unit'

    def setUp(self):
        self.myAddress = 'me'
        self.am = ActorAddressManager(None, self.myAddress)

    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 _makeLocalAndAssociated(self):
        lclAddr = self.am.createLocalAddress()
        mainAddr = ActorAddress(id(lclAddr))
        self.am.associateUseableAddress(
            self.myAddress, lclAddr.addressDetails.addressInstanceNum,
            mainAddr)
        return lclAddr, mainAddr

    def testAssociationRemembered(self):
        lclAddr, mainAddr = self._makeLocalAndAssociated()
        self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr))
        self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr))

    def testAssociationUnique(self):
        self.testAssociationRemembered()
        lclAddr2 = self.am.createLocalAddress()
        self.assertIsNone(self.am.sendToAddress(lclAddr2))

    def testAssociationNotRequiredForUseableNonLocal(self):
        addr = ActorAddress(id(self))
        self.assertEqual(addr, self.am.sendToAddress(addr))

    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 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 testAssociatedAddressesDoNotMatchArbitraryStuff(self):
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated()

        self.assertNotEqual(None, lclAddr1)
        self.assertNotEqual(id(self), lclAddr1)
        self.assertNotEqual(0, lclAddr1)
        self.assertNotEqual("hi", lclAddr1)
        self.assertNotEqual(unittest.TestCase, lclAddr1)

        self.assertNotEqual(None, mainAddr1)
        self.assertNotEqual(id(self), mainAddr1)
        self.assertNotEqual(0, mainAddr1)
        self.assertNotEqual("hi", mainAddr1)
        self.assertNotEqual(unittest.TestCase, mainAddr1)

        self.assertNotEqual(lclAddr1, None)
        self.assertNotEqual(lclAddr1, id(self))
        self.assertNotEqual(lclAddr1, 0)
        self.assertNotEqual(lclAddr1, "hi")
        self.assertNotEqual(lclAddr1, unittest.TestCase)

        self.assertNotEqual(mainAddr1, None)
        self.assertNotEqual(mainAddr1, id(self))
        self.assertNotEqual(mainAddr1, 0)
        self.assertNotEqual(mainAddr1, "hi")
        self.assertNotEqual(mainAddr1, unittest.TestCase)

    def testAssociatedAddressEqualityIsUnique(self):
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated()
        print('Set 1: %s --> %s' % (str(lclAddr1), str(mainAddr1)))
        lclAddr2, mainAddr2 = self._makeLocalAndAssociated()
        print('Set 2: %s --> %s' % (str(lclAddr2), str(mainAddr2)))
        lclAddr3, mainAddr3 = self._makeLocalAndAssociated()
        print('Set 3: %s --> %s' % (str(lclAddr3), str(mainAddr3)))

        self.assertEqual(lclAddr1, lclAddr1)
        self.assertEqual(lclAddr2, lclAddr2)
        self.assertEqual(lclAddr3, lclAddr3)

        self.assertEqual(mainAddr1, mainAddr1)
        self.assertEqual(mainAddr2, mainAddr2)
        self.assertEqual(mainAddr3, mainAddr3)

        self.assertEqual(lclAddr1, mainAddr1)
        self.assertEqual(lclAddr2, mainAddr2)
        self.assertEqual(lclAddr3, mainAddr3)

        self.assertEqual(mainAddr1, lclAddr1)
        self.assertEqual(mainAddr2, lclAddr2)
        self.assertEqual(mainAddr3, lclAddr3)

        self.assertNotEqual(lclAddr1, lclAddr2)
        self.assertNotEqual(lclAddr2, lclAddr1)
        self.assertNotEqual(lclAddr3, lclAddr2)
        self.assertNotEqual(lclAddr2, lclAddr3)
        self.assertNotEqual(lclAddr3, lclAddr1)
        self.assertNotEqual(lclAddr1, lclAddr3)

        self.assertNotEqual(mainAddr1, mainAddr2)
        self.assertNotEqual(mainAddr2, mainAddr1)
        self.assertNotEqual(mainAddr3, mainAddr2)
        self.assertNotEqual(mainAddr2, mainAddr3)
        self.assertNotEqual(mainAddr3, mainAddr1)
        self.assertNotEqual(mainAddr1, mainAddr3)

        self.assertNotEqual(mainAddr1, lclAddr2)
        self.assertNotEqual(mainAddr2, lclAddr1)
        self.assertNotEqual(mainAddr3, lclAddr2)
        self.assertNotEqual(mainAddr2, lclAddr3)
        self.assertNotEqual(mainAddr3, lclAddr1)
        self.assertNotEqual(mainAddr1, lclAddr3)

        self.assertNotEqual(lclAddr1, mainAddr2)
        self.assertNotEqual(lclAddr2, mainAddr1)
        self.assertNotEqual(lclAddr3, mainAddr2)
        self.assertNotEqual(lclAddr2, mainAddr3)
        self.assertNotEqual(lclAddr3, mainAddr1)
        self.assertNotEqual(lclAddr1, mainAddr3)
Example #23
0
    def testAssociatedAddressRevocationIsUnique(self):
        myAddress = 'me'
        am = ActorAddressManager(None, myAddress)
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated(myAddress, am)
        print('1', str(lclAddr1), str(mainAddr1))
        lclAddr2, mainAddr2 = self._makeLocalAndAssociated(myAddress, am)
        print('2', str(lclAddr2), str(mainAddr2))
        lclAddr3, mainAddr3 = self._makeLocalAndAssociated(myAddress, am)
        print('3', str(lclAddr3), str(mainAddr3))

        assert not am.isDeadAddress(lclAddr1)
        assert not am.isDeadAddress(mainAddr1)
        print('1sm', str(am.sendToAddress(mainAddr1)))
        assert not am.isDeadAddress(am.sendToAddress(mainAddr1))
        print('1sl', str(am.sendToAddress(lclAddr1)))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr1))

        assert not am.isDeadAddress(lclAddr2)
        assert not am.isDeadAddress(mainAddr2)
        assert not am.isDeadAddress(am.sendToAddress(mainAddr2))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr2))

        assert not am.isDeadAddress(lclAddr3)
        assert not am.isDeadAddress(mainAddr3)
        assert not am.isDeadAddress(am.sendToAddress(mainAddr3))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr3))

        am.deadAddress(lclAddr1)
        am.deadAddress(mainAddr2)

        assert am.isDeadAddress(lclAddr1)
        assert am.isDeadAddress(mainAddr1)
        assert am.isDeadAddress(am.sendToAddress(mainAddr1))
        assert am.isDeadAddress(am.sendToAddress(lclAddr1))

        assert am.isDeadAddress(lclAddr2)
        assert am.isDeadAddress(mainAddr2)
        assert am.isDeadAddress(am.sendToAddress(mainAddr2))
        assert am.isDeadAddress(am.sendToAddress(lclAddr2))

        assert not am.isDeadAddress(lclAddr3)
        assert not am.isDeadAddress(mainAddr3)
        assert not am.isDeadAddress(am.sendToAddress(mainAddr3))
        assert not am.isDeadAddress(am.sendToAddress(lclAddr3))
class TestAddressManagerLocalAddressAssociations(unittest.TestCase):
    scope='unit'

    def setUp(self):
        self.myAddress = 'me'
        self.am = ActorAddressManager(None, self.myAddress)

    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 _makeLocalAndAssociated(self):
        lclAddr = self.am.createLocalAddress()
        mainAddr = ActorAddress(id(lclAddr))
        self.am.associateUseableAddress(self.myAddress,
                                        lclAddr.addressDetails.addressInstanceNum,
                                        mainAddr)
        return lclAddr, mainAddr

    def testAssociationRemembered(self):
        lclAddr, mainAddr = self._makeLocalAndAssociated()
        self.assertEqual(mainAddr, self.am.sendToAddress(lclAddr))
        self.assertEqual(mainAddr, self.am.sendToAddress(mainAddr))

    def testAssociationUnique(self):
        self.testAssociationRemembered()
        lclAddr2 = self.am.createLocalAddress()
        self.assertIsNone(self.am.sendToAddress(lclAddr2))

    def testAssociationNotRequiredForUseableNonLocal(self):
        addr = ActorAddress(id(self))
        self.assertEqual(addr, self.am.sendToAddress(addr))

    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 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 testAssociatedAddressesDoNotMatchArbitraryStuff(self):
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated()

        self.assertNotEqual(None, lclAddr1)
        self.assertNotEqual(id(self), lclAddr1)
        self.assertNotEqual(0, lclAddr1)
        self.assertNotEqual("hi", lclAddr1)
        self.assertNotEqual(unittest.TestCase, lclAddr1)

        self.assertNotEqual(None, mainAddr1)
        self.assertNotEqual(id(self), mainAddr1)
        self.assertNotEqual(0, mainAddr1)
        self.assertNotEqual("hi", mainAddr1)
        self.assertNotEqual(unittest.TestCase, mainAddr1)

        self.assertNotEqual(lclAddr1, None)
        self.assertNotEqual(lclAddr1, id(self))
        self.assertNotEqual(lclAddr1, 0)
        self.assertNotEqual(lclAddr1, "hi")
        self.assertNotEqual(lclAddr1, unittest.TestCase)

        self.assertNotEqual(mainAddr1, None)
        self.assertNotEqual(mainAddr1, id(self))
        self.assertNotEqual(mainAddr1, 0)
        self.assertNotEqual(mainAddr1, "hi")
        self.assertNotEqual(mainAddr1, unittest.TestCase)

    def testAssociatedAddressEqualityIsUnique(self):
        lclAddr1, mainAddr1 = self._makeLocalAndAssociated()
        print('Set 1: %s --> %s'%(str(lclAddr1), str(mainAddr1)))
        lclAddr2, mainAddr2 = self._makeLocalAndAssociated()
        print('Set 2: %s --> %s'%(str(lclAddr2), str(mainAddr2)))
        lclAddr3, mainAddr3 = self._makeLocalAndAssociated()
        print('Set 3: %s --> %s'%(str(lclAddr3), str(mainAddr3)))

        self.assertEqual(lclAddr1, lclAddr1)
        self.assertEqual(lclAddr2, lclAddr2)
        self.assertEqual(lclAddr3, lclAddr3)

        self.assertEqual(mainAddr1, mainAddr1)
        self.assertEqual(mainAddr2, mainAddr2)
        self.assertEqual(mainAddr3, mainAddr3)

        self.assertEqual(lclAddr1, mainAddr1)
        self.assertEqual(lclAddr2, mainAddr2)
        self.assertEqual(lclAddr3, mainAddr3)

        self.assertEqual(mainAddr1, lclAddr1)
        self.assertEqual(mainAddr2, lclAddr2)
        self.assertEqual(mainAddr3, lclAddr3)

        self.assertNotEqual(lclAddr1, lclAddr2)
        self.assertNotEqual(lclAddr2, lclAddr1)
        self.assertNotEqual(lclAddr3, lclAddr2)
        self.assertNotEqual(lclAddr2, lclAddr3)
        self.assertNotEqual(lclAddr3, lclAddr1)
        self.assertNotEqual(lclAddr1, lclAddr3)

        self.assertNotEqual(mainAddr1, mainAddr2)
        self.assertNotEqual(mainAddr2, mainAddr1)
        self.assertNotEqual(mainAddr3, mainAddr2)
        self.assertNotEqual(mainAddr2, mainAddr3)
        self.assertNotEqual(mainAddr3, mainAddr1)
        self.assertNotEqual(mainAddr1, mainAddr3)

        self.assertNotEqual(mainAddr1, lclAddr2)
        self.assertNotEqual(mainAddr2, lclAddr1)
        self.assertNotEqual(mainAddr3, lclAddr2)
        self.assertNotEqual(mainAddr2, lclAddr3)
        self.assertNotEqual(mainAddr3, lclAddr1)
        self.assertNotEqual(mainAddr1, lclAddr3)

        self.assertNotEqual(lclAddr1, mainAddr2)
        self.assertNotEqual(lclAddr2, mainAddr1)
        self.assertNotEqual(lclAddr3, mainAddr2)
        self.assertNotEqual(lclAddr2, mainAddr3)
        self.assertNotEqual(lclAddr3, mainAddr1)
        self.assertNotEqual(lclAddr1, mainAddr3)