def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0) self.baseDirpath = tempfile.mkdtemp(prefix="raet", suffix="base", dir=TEMPDIR) self.stack = None # This has to be set to True in the only one process that would perform tearDown steps self.engine = True stacking.RoadStack.BurstSize = 100
def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0) self.baseDirpath=tempfile.mkdtemp(prefix="raet", suffix="base", dir=TEMPDIR) stacking.RoadStack.Bk = raeting.BodyKind.json.value #main stack mainName = "main" mainDirpath = os.path.join(self.baseDirpath, 'road', 'keep', mainName) signer = nacling.Signer() mainSignKeyHex = signer.keyhex privateer = nacling.Privateer() mainPriKeyHex = privateer.keyhex #other stack otherName = "other" otherDirpath = os.path.join(self.baseDirpath, 'road', 'keep', otherName) signer = nacling.Signer() otherSignKeyHex = signer.keyhex privateer = nacling.Privateer() otherPriKeyHex = privateer.keyhex keeping.clearAllKeep(mainDirpath) keeping.clearAllKeep(otherDirpath) self.main = stacking.RoadStack(store=self.store, name=mainName, main=True, auto=raeting.AutoMode.once.value, sigkey=mainSignKeyHex, prikey=mainPriKeyHex, dirpath=mainDirpath, ) self.other = stacking.RoadStack(store=self.store, name=otherName, auto=raeting.AutoMode.once.value, ha=("", raeting.RAET_TEST_PORT), sigkey=otherSignKeyHex, prikey=otherPriKeyHex, dirpath=otherDirpath, )
def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0) if sys.platform == 'win32': self.tempDirpath = tempfile.mktemp(prefix="raet", suffix="base", dir=TEMPDIR) else: self.tempDirpath = tempfile.mkdtemp(prefix="raet", suffix="base", dir=TEMPDIR) self.baseDirpath = os.path.join(self.tempDirpath, 'lane', 'keep') # main stack self.main = stacking.LaneStack(name='main', uid=1, lanename='cherry', sockdirpath=self.baseDirpath) #other stack self.other = stacking.LaneStack(name='other', uid=1, lanename='cherry', sockdirpath=self.baseDirpath)
def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0)
def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0) self.dirpathBase = tempfile.mkdtemp(prefix="raet", suffix="base", dir=TEMPDIR) stacking.RoadStack.Bk = raeting.BodyKind.json.value #main stack mainName = "main" mainDirpath = os.path.join(self.dirpathBase, 'road', 'keep', mainName) signer = nacling.Signer() mainSignKeyHex = signer.keyhex mainVerKeyHex = signer.verhex privateer = nacling.Privateer() mainPriKeyHex = privateer.keyhex mainPubKeyHex = privateer.pubhex #other stack otherName = "other" otherDirpath = os.path.join(self.dirpathBase, 'road', 'keep', otherName) signer = nacling.Signer() otherSignKeyHex = signer.keyhex otherVerKeyHex = signer.verhex privateer = nacling.Privateer() otherPriKeyHex = privateer.keyhex otherPubKeyHex = privateer.pubhex keeping.clearAllKeep(mainDirpath) keeping.clearAllKeep(otherDirpath) self.main = stacking.RoadStack(name=mainName, uid=1, sigkey=mainSignKeyHex, prikey=mainPriKeyHex, auto=raeting.AutoMode.once.value, main=True, dirpath=mainDirpath, store=self.store) remote1 = estating.RemoteEstate( stack=self.main, uid=2, name=otherName, ha=("127.0.0.1", raeting.RAET_TEST_PORT), verkey=otherVerKeyHex, pubkey=otherPubKeyHex, ) self.main.addRemote(remote1) self.other = stacking.RoadStack(name=otherName, uid=2, auto=raeting.AutoMode.once.value, ha=("", raeting.RAET_TEST_PORT), sigkey=otherSignKeyHex, prikey=otherPriKeyHex, dirpath=otherDirpath, store=self.store) remote0 = estating.RemoteEstate( stack=self.other, uid=3, name=mainName, ha=('127.0.0.1', raeting.RAET_PORT), verkey=mainVerKeyHex, pubkey=mainPubKeyHex, ) self.other.addRemote(remote0) remote0.publee = nacling.Publican(key=remote1.privee.pubhex) remote1.publee = nacling.Publican(key=remote0.privee.pubhex) stuff = [] for i in range(300): stuff.append(str(i).rjust(4, " ")) self.stuff = ns2b("".join(stuff)) self.data = odict(hk=raeting.HeadKind.raet.value)
def __init__( self, store=None, version=raeting.VERSION, main=None, puid=None, local=None, #passed up from subclass name='', uid=None, server=None, ha=None, bufcnt=2, rxMsgs=None, txMsgs=None, rxes=None, txes=None, stats=None, ): ''' Setup Stack instance ''' self.store = store or Store(stamp=0.0) self.version = version self.main = main if getattr(self, 'puid', None) is None: self.puid = puid if puid is not None else self.Uid self.local = local or lotting.Lot( stack=self, name=name, uid=uid, ha=ha, ) self.local.stack = self self.remotes = self.uidRemotes = odict() # remotes indexed by uid self.nameRemotes = odict() # remotes indexed by name self.bufcnt = bufcnt if not server: server = self.serverFromLocal() self.server = server if self.server: if not self.server.reopen(): # open socket raise raeting.StackError( "Stack '{0}': Failed opening server at" " '{1}'\n".format(self.name, self.server.ha)) self.ha = self.server.ha # update local host address after open console.verbose("Stack '{0}': Opened server at '{1}'\n".format( self.name, self.ha)) self.rxMsgs = rxMsgs if rxMsgs is not None else deque( ) # messages received self.txMsgs = txMsgs if txMsgs is not None else deque( ) # messages to transmit self.rxes = rxes if rxes is not None else deque( ) # udp packets received self.txes = txes if txes is not None else deque( ) # udp packet to transmit self.stats = stats if stats is not None else odict() # udp statistics self.statTimer = StoreTimer(self.store)
class BasicLoadTestCase(unittest.TestCase): ''' Base class for load tests. Provides generic master/slave runners with flooding and checking logic. ''' def __init__(self, *args, **kwargs): super(BasicLoadTestCase, self).__init__(*args, **kwargs) def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0) self.baseDirpath = tempfile.mkdtemp(prefix="raet", suffix="base", dir=TEMPDIR) self.stack = None # This has to be set to True in the only one process that would perform tearDown steps self.engine = True stacking.RoadStack.BurstSize = 100 def tearDown(self): # The only engine have to tear down stacks after all workers have done if not self.engine: if self.stack: self.stack.server.close() self.stack.clearAllDir() else: if os.path.exists(self.baseDirpath): shutil.rmtree(self.baseDirpath) def createStack(self, name, port): ''' Create a RoadStack object bound to the specified port on localhost. :param name: stack name :param port: port to bind to :return: the stack ''' dirpath = os.path.join(self.baseDirpath, 'road', 'keep', name) signer = nacling.Signer() mainSignKeyHex = signer.keyhex privateer = nacling.Privateer() mainPriKeyHex = privateer.keyhex keeping.clearAllKeep(dirpath) return stacking.RoadStack(store=self.store, name=name, main=True, auto=raeting.AutoMode.once.value, ha=("", port), sigkey=mainSignKeyHex, prikey=mainPriKeyHex, dirpath=dirpath, ) def joinAll(self, initiator, correspondentAddresses, timeout=None, retryCount=1): ''' Utility method to do join. :param initiator: join initiator stack :param correspondentAddresses: an iterable object containing ha tuples :param timeout: join timeout, will be passed to stack :param retryCount: retry join max the specified count of times until success ''' console.terse("\nJoin Transaction **************\n") addresses = list(correspondentAddresses) for ha in addresses: initiator.addRemote(estating.RemoteEstate(stack=initiator, fuid=0, # vacuous join sid=0, # always 0 for join ha=ha)) while retryCount > 0: done = True for remote in initiator.remotes.values(): if not remote.joined: done = False initiator.join(uid=remote.uid, timeout=timeout) self.serviceOne(initiator) if done: break retryCount -= 1 def allowAll(self, initiator, timeout=None, retryCount=1): ''' Utility method to do allow. :param initiator: allow initiator stack :param timeout: allow timeout, will be passed to stack :param retryCount: retry allow max the specified count of times until success ''' console.terse("\nAllow Transaction **************\n") while retryCount > 0: done = True for remote in initiator.remotes.values(): if not remote.allowed: done = False initiator.allow(uid=remote.uid, timeout=timeout) self.serviceOne(initiator) if done: break retryCount -= 1 def serviceAll(self, stacks, duration=100.0, timeout=0.0, step=0.1, exitCase=None): ''' Utility method to service queues. :param stacks: iterable containing stacks to service :param duration: max service duration, actually could finish earlier if there still no transactions to service :param timeout: time to continue service even if there are no transactions :param step: timer step :param exitCase: stop immediately if this function return true :return: actual exit reason, could be one of 'duration', 'exitCase' or 'timeout' ''' self.timer.restart(duration=duration) empty = False elapsed = self.timer.getElapsed() retReason = 'duration' while not self.timer.expired: for stack in stacks: stack.serviceAll() if any(stack.transactions for stack in stacks): empty = False # reset nop timeout else: if exitCase and exitCase(): retReason = 'exitCase' break if empty: if self.timer.getElapsed() - elapsed > timeout: retReason = 'timeout' break else: empty = True elapsed = self.timer.getElapsed() self.store.advanceStamp(step) time.sleep(step) return retReason def serviceOne(self, stack, duration=100.0, timeout=0.0, step=0.1, exitCase=None): ''' Utility method to service one stack. See :func:`serviceStacks`. ''' return self.serviceAll([stack], duration, timeout, step, exitCase) def bidirectional(self, stack, duration=3.0): ''' Simultaneously sends and receives test messages. - self.msgSize: message size - self.msgCount: per remote message count :param stack: the stack to service :param duration: service duration to prevent hang ''' console.terse("\nMessages Bidirectional {0} *********\n".format(stack.name)) verifier = data.MessageVerifier(size=self.msgSize, msgCount=self.msgCount, remoteCount=len(stack.remotes), house='manor', queue='stuff') received = 0 expected = len(stack.remotes) * self.msgCount maxTransactions = MAX_TRANSACTIONS * len(stack.remotes) for msg in data.generateMessages(name=stack.name, size=self.msgSize, count=self.msgCount): for remote in stack.remotes.values(): # send message stack.transmit(msg, uid=remote.uid) # service while there are too much transactions (but loops at least once) while True: self.serviceOne(stack, duration=0.01, step=0.01) # check received if stack.rxMsgs: received += len(stack.rxMsgs) while stack.rxMsgs: verifier.verifyMessage(stack.rxMsgs.popleft()) # keep servicing if there are a lot of transactions if len(stack.transactions) <= maxTransactions: break # all sent, continue handle received while received < expected: self.serviceOne(stack, duration=duration, timeout=duration, exitCase=lambda: stack.rxMsgs) # if received nothing during timeout, assume we're done if not stack.rxMsgs: break received += len(stack.rxMsgs) while stack.rxMsgs: verifier.verifyMessage(stack.rxMsgs.popleft()) # wait remaining messenger transactions if any to be closed if stack.transactions: self.serviceOne(stack, duration=duration) # Done. Wait others self.doneCounter.inc() elapsed = 0.0 # be safe from engine unexpected stop step = 1.0 while not self.stopFlag.get() and elapsed < duration * 2: self.serviceOne(stack, duration=step, timeout=step) elapsed += step # check result console.terse("\nStack '{0}' uid={1}\n\tTransactions: {2}\n\trcv/exp: {3}/{4}\n\tStats: {5}\n" .format(stack.name, stack.local.uid, stack.transactions, received, expected, stack.stats)) rcvErrors = verifier.checkAllDone() if rcvErrors: console.terse("{0} received message with the following errors:\n".format(stack.name)) for s in rcvErrors: console.terse("\t{0} from {1}\n".format(stack.name, s)) self.assertEqual(len(stack.transactions), 0) self.assertEqual(len(rcvErrors), 0) self.assertEqual(received, expected) def send(self, stack, duration=3.0): ''' Sends test messages. - self.msgSize: message size - self.msgCount: per remote message count :param stack: the stack to service :param duration: service duration to prevent hang ''' console.terse("\nMessages Sender {0} *********\n".format(stack.name)) maxTransactions = MAX_TRANSACTIONS * len(stack.remotes) for msg in data.generateMessages(name=stack.name, size=self.msgSize, count=self.msgCount): for remote in stack.remotes.values(): # send message stack.transmit(msg, uid=remote.uid) # service while there are too much transactions (but loops at least once) while True: self.serviceOne(stack, duration=0.01, step=0.01) if len(stack.transactions) <= maxTransactions: break # done, wait others self.doneCounter.inc() elapsed = 0.0 # be safe from engine unexpected stop step = 1.0 while not self.stopFlag.get() and elapsed < duration * 2: self.serviceOne(stack, duration=step, timeout=step) elapsed += step # check result console.terse("\nStack '{0}' uid={1}\n\tTransactions: {2}\n\tStats: {3}\n" .format(stack.name, stack.local.uid, stack.transactions, stack.stats)) self.assertEqual(len(stack.transactions), 0) self.assertEqual(len(stack.rxMsgs), 0) def receive(self, stack, duration=3.0): ''' Receives test messages. - self.msgSize: message size - self.msgCount: per remote message count :param stack: the stack to service :param duration: service duration to prevent hang ''' console.terse("\nMessages Receiver {0} *********\n".format(stack.name)) verifier = data.MessageVerifier(size=self.msgSize, msgCount=self.msgCount, remoteCount=len(stack.remotes), house='manor', queue='stuff') # Receive messages received = 0 expected = len(stack.remotes) * self.msgCount while received < expected: reason = self.serviceOne(stack, duration=duration, timeout=duration, exitCase=lambda: stack.rxMsgs) console.terse("{0} service exit reason: {1}, transactions: {2}\n".format( stack.name, reason, stack.transactions)) # received nothing during timeout, assume there is nothing to receive if not stack.rxMsgs: break received += len(stack.rxMsgs) while stack.rxMsgs: verifier.verifyMessage(stack.rxMsgs.popleft()) # Done. Wait others self.doneCounter.inc() elapsed = 0.0 # be safe from engine unexpected stop step = 1.0 while not self.stopFlag.get() and elapsed < duration * 2: self.serviceOne(stack, duration=step, timeout=step) elapsed += step # Verify results console.terse("\nStack '{0}' uid={1}\n\tTransactions: {2}\n\trcv/exp: {3}/{4}\n\tStats: {5}\n" .format(stack.name, stack.local.uid, stack.transactions, received, expected, stack.stats)) for t in stack.transactions: if isinstance(t, transacting.Messengent): print("Tray lost segments: {0}\n".format([i for i, x in enumerate(t.tray.segments) if x is None])) rcvErrors = verifier.checkAllDone() if rcvErrors: console.terse("{0} received message with the following errors:\n".format(stack.name)) for s in rcvErrors: console.terse("\t{0} from {1}\n".format(stack.name, s)) self.assertEqual(len(stack.transactions), 0) self.assertEqual(len(rcvErrors), 0) self.assertEqual(received, expected) def masterPeer(self, name, port, minionCount, action): ''' Master peer main function. It creates a RoadStack, sends/receives a bunch of test messages to remote peers and checks the result :param name: the name of this peer :param port: port to bind to :param minionCount: count of remote peers :param action: action function. Could be one of self.send, self.receive or self.bidirectional :return: if done without errors the process will end with 0 exit code ''' self.engine = False # create stack self.stack = self.createStack(name, port) console.terse("\nCreated {0} at {1} *********\n".format(name, self.stack.ha)) console.terse("\n{0} Waiting For Minions *********\n".format(name)) # wait minions to join and allow def isBootstrapDone(): if not self.stack.remotes: return False if len(self.stack.remotes) != minionCount: return False for rmt in self.stack.remotes.values(): if not rmt.allowed: return False return True serviceCode = self.serviceOne(self.stack, timeout=100.0, exitCase=isBootstrapDone) console.terse("\n{0} bootstrap done with code {1}".format(name, serviceCode)) # verify all minions connected self.assertEqual(len(self.stack.transactions), 0) self.assertEqual(len(self.stack.remotes), minionCount) for remote in self.stack.remotes.values(): self.assertTrue(remote.joined) self.assertTrue(remote.allowed) console.terse("\n{0} Bootstrap Done ({1}) *********\n".format(name, serviceCode)) # do the job action(self.stack, duration=self.duration) def minionPeer(self, name, port, remoteAddresses, action): ''' Slave peer main function. It creates a RoadStack, sends/receives a bunch of test messages to remote peers and checks the result :param name: the name of this peer :param port: port to bind to :param minionCount: count of remote peers :param action: action function. Could be one of self.send, self.receive or self.bidirectional :return: if done without errors the process will end with 0 exit code ''' self.engine = False # Create stack self.stack = self.createStack(name, port) console.terse("\nCreated {0} at {1} *********\n".format(name, self.stack.ha)) console.terse("\n{0} Joining Remotes *********\n".format(name)) # join with all masters self.joinAll(self.stack, remoteAddresses, retryCount=10) self.assertEqual(len(self.stack.transactions), 0) self.assertEqual(len(self.stack.remotes), len(remoteAddresses)) for remote in self.stack.remotes.values(): self.assertTrue(remote.joined, "{0}: remote '{1}' at {2} is not joined".format( name, remote.name, remote.ha)) console.terse("\n{0} Allowing Remotes *********\n".format(name)) # allow all masters self.allowAll(self.stack, retryCount=10) self.assertEqual(len(self.stack.transactions), 0) self.assertEqual(len(self.stack.remotes), len(remoteAddresses)) for remote in self.stack.remotes.values(): self.assertTrue(remote.allowed, "{0}: remote '{1}' at {2} is not allowed".format( name, remote.name, remote.ha)) console.terse("\n{0} Bootstrap Done *********\n".format(name)) # do the job action(self.stack, duration=self.duration) def messagingMultiPeers(self, masterCount, minionCount, msgSize, msgCount, duration, direction): ''' Perform the test. This function creates a number of processes which are master and slave network peers. Each process sends a bunch of messages to each process from the opposite group (for bidirectional case) :param masterCount: count of master peers :param minionCount: count of slave peers :param msgSize: size of the message stuff, actually the message would be bigger :param msgCount: count of messages to be sent from peer to peer :param duration: test duration limit, will be used in service calls so actual allowed duration will be greater :param direction: sending duration, could be one of DIR_TO_MASTER, DIR_FROM_MASTER or DIR_BIDIRECTIONAL :return: throw PyUnit assertion if fail ''' self.masterCount = masterCount self.minionCount = minionCount self.msgSize = msgSize self.msgCount = msgCount self.duration = duration masterDir = {DIR_BIDIRECTIONAL: self.bidirectional, DIR_TO_MASTER: self.receive, DIR_FROM_MASTER: self.send} minionDir = {DIR_BIDIRECTIONAL: self.bidirectional, DIR_TO_MASTER: self.send, DIR_FROM_MASTER: self.receive} # create masters port = raeting.RAET_PORT masterHostAddresses = [] masterProcs = [] self.doneCounter = mp_helper.Counter() self.stopFlag = mp_helper.Counter() for i in xrange(masterCount): masterHostAddresses.append(('', port)) name = 'master{0}'.format(i) masterProc = multiprocessing.Process(target=self.masterPeer, name=name, args=(name, port, minionCount, masterDir[direction])) masterProcs.append(masterProc) port += 1 # create minions minionProcs = [] for i in xrange(minionCount): name = 'minion{0}'.format(i) minionProc = multiprocessing.Process(target=self.minionPeer, name=name, args=(name, port, masterHostAddresses, minionDir[direction])) minionProcs.append(minionProc) port += 1 # start masters first for proc in masterProcs: proc.start() time.sleep(1.0) # let masters start # start minions for proc in minionProcs: proc.start() # wait until all workers done their job elapsed = 0.0 # be safe from worker unexpected stop step = 1.0 while self.doneCounter.get() < masterCount + minionCount and elapsed < duration * 2: time.sleep(step) elapsed += step # set stop flag self.stopFlag.inc() # wait all processes exited for procs in (masterProcs, minionProcs): for proc in procs: proc.join() # ensure all workers successfully done for procs in (masterProcs, minionProcs): for proc in procs: self.assertEqual(proc.exitcode, 0, "'{0}' returned {1}".format(proc.name, proc.exitcode))
class BasicTestCase(unittest.TestCase): """""" def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0) if sys.platform == 'win32': self.tempDirpath = tempfile.mktemp(prefix="raet", suffix="base", dir=TEMPDIR) else: self.tempDirpath = tempfile.mkdtemp(prefix="raet", suffix="base", dir=TEMPDIR) self.baseDirpath = os.path.join(self.tempDirpath, 'lane', 'keep') # main stack self.main = stacking.LaneStack(name='main', uid=1, lanename='cherry', sockdirpath=self.baseDirpath) #other stack self.other = stacking.LaneStack(name='other', uid=1, lanename='cherry', sockdirpath=self.baseDirpath) def tearDown(self): self.main.server.close() self.other.server.close() if not sys.platform == 'win32': shutil.rmtree(self.tempDirpath) def service(self, duration=1.0, real=True): ''' Utility method to service queues. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: self.other.serviceAll() self.main.serviceAll() self.store.advanceStamp(0.1) if real: time.sleep(0.1) def serviceOther(self, duration=1.0, real=True): ''' Utility method to only service other queues. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: self.other.serviceAll() self.store.advanceStamp(0.1) if real: time.sleep(0.1) def serviceMain(self, duration=1.0, real=True): ''' Utility method to only service main queues. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: self.main.serviceAll() self.store.advanceStamp(0.1) if real: time.sleep(0.1) def bootstrap(self, kind=raeting.PackKind.json.value): ''' Basic messaging ''' self.main.addRemote(yarding.RemoteYard(stack=self.main, ha=self.other.ha)) self.other.addRemote(yarding.RemoteYard(stack=self.other, ha=self.main.ha)) self.assertEqual(self.main.name, 'main') self.assertEqual(self.main.local.name, 'main') self.assertEqual(self.main.ha, os.path.join(self.baseDirpath, 'cherry.main.uxd')) self.assertEqual(len(self.main.remotes), 1) remote = self.main.remotes.values()[0] self.assertEqual(remote.ha, os.path.join(self.baseDirpath, 'cherry.other.uxd')) self.assertEqual(remote.name, 'other') self.assertTrue(remote.uid in self.main.remotes) self.assertTrue(remote.name in self.main.nameRemotes) self.assertTrue(remote.ha in self.main.haRemotes) self.assertIs(self.main.nameRemotes[remote.name], remote) self.assertIs(self.main.haRemotes[remote.ha], remote) self.assertEqual(self.other.name, 'other') self.assertEqual(self.other.local.name, 'other') self.assertEqual(self.other.ha, os.path.join(self.baseDirpath, 'cherry.other.uxd')) self.assertEqual(len(self.other.remotes), 1) remote = self.other.remotes.values()[0] self.assertEqual(remote.ha, os.path.join(self.baseDirpath, 'cherry.main.uxd')) self.assertEqual(remote.name, 'main') self.assertTrue(remote.uid in self.other.remotes) self.assertTrue(remote.name in self.other.nameRemotes) self.assertTrue(remote.ha in self.other.haRemotes) self.assertIs(self.other.nameRemotes[remote.name], remote) self.assertIs(self.other.haRemotes[remote.ha], remote) stacking.LaneStack.Pk = kind def message(self, mains, others, duration=1.0): ''' Transmit and receive messages in mains and others lists ''' for msg in mains: self.main.transmit(msg=msg) for msg in others: self.other.transmit(msg=msg) self.service(duration=duration) self.assertEqual(len(self.main.rxMsgs), len(others)) for i, duple in enumerate(self.main.rxMsgs): console.terse("Yard '{0}' rxed:\n'{1}'\n".format(self.main.local.name, duple)) self.assertDictEqual(others[i], duple[0]) self.assertEqual(len(self.other.rxMsgs), len(mains)) for i, duple in enumerate(self.other.rxMsgs): console.terse("Yard '{0}' rxed:\n'{1}'\n".format(self.other.local.name, duple)) self.assertDictEqual(mains[i], duple[0]) def createLaneData(self, name, uid, base, lanename): ''' Creates odict and populates with data to setup lane stack { name: stack name dirpath: dirpath for keep files lanename: name of yard } ''' data = odict() data['name'] = name data['uid'] = uid data['sockdirpath'] = os.path.join(base, name) data['lanename'] = lanename return data def createLaneStack(self, data, main=None): ''' Creates stack and local yard from data returns stack ''' stack = stacking.LaneStack(name=data['name'], uid=data['uid'], main=main, lanename=data['lanename'], sockdirpath=data['sockdirpath']) return stack def serviceMainOther(self, main, other, duration=1.0): ''' Utility method to service queues. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: other.serviceAll() main.serviceAll() self.store.advanceStamp(0.1) time.sleep(0.1) def messageMainOther(self, main, other, mains, others, duration=1.0): ''' Utility to send messages both ways ''' for msg in mains: main.transmit(msg, uid=main.fetchUidByName(other.local.name)) for msg in others: other.transmit(msg, uid=other.fetchUidByName(main.local.name)) self.serviceMainOther(main, other, duration=duration) self.assertEqual(len(main.rxMsgs), len(others)) for i, duple in enumerate(main.rxMsgs): console.terse("Yard '{0}' rxed:\n'{1}'\n".format(main.local.name, duple)) self.assertDictEqual(others[i], duple[0]) self.assertEqual(len(other.rxMsgs), len(mains)) for i, duple in enumerate(other.rxMsgs): console.terse("Yard '{0}' rxed:\n'{1}'\n".format(other.local.name, duple)) self.assertDictEqual(mains[i], duple[0]) def serviceStackOneTx(self, stack): ''' Utility method to service one packet on Tx queues. Call from test method. ''' stack.serviceOneAllTx() time.sleep(0.1) self.store.advanceStamp(0.1) def serviceStackOneRx(self, stack): ''' Utility method to service one packet on Rx queues. Call from test method. ''' stack.serviceOneAllRx() time.sleep(0.1) self.store.advanceStamp(0.1) def serviceOneTx(self, main, other): ''' Utility method to service one packet on Tx queues. Call from test method. ''' other.serviceOneAllTx() main.serviceOneAllTx() time.sleep(0.1) self.store.advanceStamp(0.1) def serviceOneRx(self, main, other): ''' Utility method to service one packet on Rx queues. Call from test method. ''' other.serviceOneAllRx() main.serviceOneAllRx() time.sleep(0.1) self.store.advanceStamp(0.1) def serviceOneAll(self, main, other): ''' Utility method to service one packet on all queues. Call from test method. ''' self.serviceOneTx(main=main, other=other) self.serviceOneRx(main=main, other=other) def serviceStack(self, stack, duration=1.0): ''' Utility method to service queues for one stack. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: stack.serviceAll() self.store.advanceStamp(0.1) time.sleep(0.1) def serviceStacks(self, stacks, duration=1.0): ''' Utility method to service queues for list of stacks. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: for stack in stacks: stack.serviceAll() self.store.advanceStamp(0.1) time.sleep(0.1) def testMessageJson(self): ''' Basic messaging with json packing ''' console.terse("{0}\n".format(self.testMessageJson.__doc__)) self.bootstrap(kind=raeting.PackKind.json.value) mains = [] mains.append(odict(what="This is a message to the serf. Get to Work", extra="Fix the fence.")) others = [] others.append(odict(what="This is a message to the lord. Let me be", extra="Go away.")) self.message(mains=mains, others=others) def testMessageMsgpack(self): ''' Basic messaging with msgpack packing ''' console.terse("{0}\n".format(self.testMessageMsgpack.__doc__)) self.bootstrap(kind=raeting.PackKind.pack.value) mains = [] mains.append(odict(what="This is a message to the serf. Get to Work", extra="Fix the fence.")) others = [] others.append(odict(what="This is a message to the lord. Let me be", extra="Go away.")) self.message(mains=mains, others=others) def testMessageMultipleJson(self): ''' Multiple messages with json packing ''' console.terse("{0}\n".format(self.testMessageMultipleJson.__doc__)) self.bootstrap(kind=raeting.PackKind.json.value) mains = [] mains.append(odict([('house', "Mama mia1"), ('queue', "fix me")])) mains.append(odict([('house', "Mama mia2"), ('queue', "stop me")])) mains.append(odict([('house', "Mama mia3"), ('queue', "help me")])) mains.append(odict([('house', "Mama mia4"), ('queue', "run me")])) others = [] others.append(odict([('house', "Papa pia1"), ('queue', "fix me")])) others.append(odict([('house', "Papa pia1"), ('queue', "stop me")])) others.append(odict([('house', "Papa pia1"), ('queue', "help me")])) others.append(odict([('house', "Papa pia1"), ('queue', "run me")])) self.message(mains=mains, others=others) def testMessageMultipleMsgpack(self): ''' multiple messages with msgpack packing ''' console.terse("{0}\n".format(self.testMessageMultipleMsgpack.__doc__)) self.bootstrap(kind=raeting.PackKind.pack.value) mains = [] mains.append(odict([('house', "Mama mia1"), ('queue', "fix me")])) mains.append(odict([('house', "Mama mia2"), ('queue', "stop me")])) mains.append(odict([('house', "Mama mia3"), ('queue', "help me")])) mains.append(odict([('house', "Mama mia4"), ('queue', "run me")])) others = [] others.append(odict([('house', "Papa pia1"), ('queue', "fix me")])) others.append(odict([('house', "Papa pia1"), ('queue', "stop me")])) others.append(odict([('house', "Papa pia1"), ('queue', "help me")])) others.append(odict([('house', "Papa pia1"), ('queue', "run me")])) self.message(mains=mains, others=others) def testMessageSectionedJson(self): ''' Sectioned messages with json packing ''' console.terse("{0}\n".format(self.testMessageSectionedJson.__doc__)) self.bootstrap(kind=raeting.PackKind.json.value) #big packets stuff = [] for i in range(10000): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) src = ['mayor', self.main.local.name, None] dst = ['citizen', self.other.local.name, None] route = odict([('src', src), ('dst', dst)]) mains = [] mains.append(odict([('route', route), ('content', stuff)])) src = ['citizen', self.other.local.name, None] dst = ['mayor', self.main.local.name, None] route = odict([('src', src), ('dst', dst)]) others = [] others.append(odict([('route', route), ('content', stuff)])) self.message(mains=mains, others=others, duration=2.0) def testMessageSectionedMsgpack(self): ''' Sectioned messages with msgpack packing ''' console.terse("{0}\n".format(self.testMessageSectionedMsgpack.__doc__)) self.bootstrap(kind=raeting.PackKind.pack.value) #big packets stuff = [] for i in range(10000): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) src = ['mayor', self.main.local.name, None] dst = ['citizen', self.other.local.name, None] route = odict([('src', src), ('dst', dst)]) mains = [] mains.append(odict([('route', route), ('content', stuff)])) src = ['citizen', self.other.local.name, None] dst = ['mayor', self.main.local.name, None] route = odict([('src', src), ('dst', dst)]) others = [] others.append(odict([('route', route), ('content', stuff)])) self.message(mains=mains, others=others, duration=2.0) def testAutoAccept(self): ''' Basic send auto accept message ''' console.terse("{0}\n".format(self.testAutoAccept.__doc__)) self.assertTrue(self.main.accept) # Don't add remote yard to main so only way to get message from other is # if auto acccept works self.other.addRemote(yarding.RemoteYard(stack=self.other, ha=self.main.ha)) self.assertEqual(self.main.name, 'main') self.assertEqual(self.main.local.name, 'main') self.assertEqual(self.main.ha, os.path.join(self.baseDirpath, 'cherry.main.uxd')) self.assertEqual(len(self.main.remotes), 0) self.assertEqual(self.other.name, 'other') self.assertEqual(self.other.local.name, 'other') self.assertEqual(self.other.ha, os.path.join(self.baseDirpath, 'cherry.other.uxd')) self.assertEqual(len(self.other.remotes), 1) remote = self.other.remotes.values()[0] self.assertEqual(remote.ha, os.path.join(self.baseDirpath, 'cherry.main.uxd')) self.assertEqual(remote.name, 'main') self.assertTrue(remote.uid in self.other.remotes) self.assertTrue(remote.name in self.other.nameRemotes) self.assertTrue(remote.ha in self.other.haRemotes) self.assertIs(self.other.nameRemotes[remote.name], remote) self.assertIs(self.other.haRemotes[remote.ha], remote) stacking.LaneStack.Pk = raeting.PackKind.pack.value others = [] others.append(odict(what="This is a message to the lord. Let me be", extra="Go away.")) self.message(mains=[], others=others) self.assertEqual(len(self.main.remotes), 1) remote = self.main.remotes.values()[0] self.assertEqual(remote.ha, os.path.join(self.baseDirpath, 'cherry.other.uxd')) self.assertEqual(remote.name, 'other') self.assertTrue(remote.uid in self.main.remotes) self.assertTrue(remote.name in self.main.nameRemotes) self.assertTrue(remote.ha in self.main.haRemotes) self.assertIs(self.main.nameRemotes[remote.name], remote) self.assertIs(self.main.haRemotes[remote.ha], remote) self.main.rxMsgs = deque() self.other.rxMsgs = deque() mains = [] mains.append(odict(what="This is a message to the serf. Get to Work", extra="Fix the fence.")) self.message(mains=mains, others=[]) def testAutoAcceptNot(self): ''' Basic send non auto accept message ''' console.terse("{0}\n".format(self.testAutoAcceptNot.__doc__)) self.main.accept = False self.assertIs(self.main.accept, False) # Don't add remote yard to main so only way to get message from other is # if auto acccept works self.other.addRemote(yarding.RemoteYard(stack=self.other, ha=self.main.ha)) self.assertEqual(self.main.name, 'main') self.assertEqual(self.main.local.name, 'main') self.assertEqual(self.main.ha, os.path.join(self.baseDirpath, 'cherry.main.uxd')) self.assertEqual(len(self.main.remotes), 0) self.assertEqual(self.other.name, 'other') self.assertEqual(self.other.local.name, 'other') self.assertEqual(self.other.ha, os.path.join(self.baseDirpath, 'cherry.other.uxd')) self.assertEqual(len(self.other.remotes), 1) remote = self.other.remotes.values()[0] self.assertEqual(remote.ha, os.path.join(self.baseDirpath, 'cherry.main.uxd')) self.assertEqual(remote.name, 'main') self.assertTrue(remote.uid in self.other.remotes) self.assertTrue(remote.name in self.other.nameRemotes) self.assertTrue(remote.ha in self.other.haRemotes) self.assertIs(self.other.nameRemotes[remote.name], remote) self.assertIs(self.other.haRemotes[remote.ha], remote) stacking.LaneStack.Pk = raeting.PackKind.pack.value others = [] others.append(odict(what="This is a message to the lord. Let me be", extra="Go away.")) for msg in others: self.other.transmit(msg=msg) self.service() self.assertEqual(len(self.main.rxMsgs), 0) self.assertEqual(len(self.main.remotes), 0) self.assertEqual(self.main.stats['unaccepted_source_yard'], 1) def testFetchRemoteFromHa(self): ''' Fetching remote yard by HA ''' console.terse("{0}\n".format(self.testFetchRemoteFromHa.__doc__)) self.bootstrap(kind=raeting.PackKind.json.value) for remote in self.main.remotes.values(): fetched = self.main.haRemotes.get(remote.ha) self.assertIs(remote, fetched) for remote in self.other.remotes.values(): fetched = self.other.haRemotes.get(remote.ha) self.assertIs(remote, fetched) def testRestart(self): ''' Test messaging after restart ''' console.terse("{0}\n".format(self.testRestart.__doc__)) stacking.LaneStack.Pk = raeting.PackKind.json.value mainData = self.createLaneData(name='main', uid=1, base=self.baseDirpath, lanename='apple') main = self.createLaneStack(data=mainData, main=True) self.assertTrue(main.ha.endswith(os.path.join('lane','keep','main', 'apple.main.uxd'))) self.assertTrue(main.main) otherData = self.createLaneData(name='other', uid=1, base=self.baseDirpath, lanename='apple') other = self.createLaneStack(data=otherData) self.assertTrue(other.ha.endswith(os.path.join('lane','keep','other', 'apple.other.uxd'))) main.addRemote(yarding.RemoteYard(stack=main, ha=other.ha)) self.assertTrue('other' in main.nameRemotes) self.assertTrue(other.ha in main.haRemotes) other.addRemote(yarding.RemoteYard(stack=other, ha=main.ha)) self.assertTrue('main' in other.nameRemotes) self.assertTrue(main.ha in other.haRemotes) src = ['mayor', main.local.name, None] # (house, yard, queue) dst = ['citizen', other.local.name, None] route = odict([('src', src), ('dst', dst)]) stuff = "This is my command" mains = [] mains.append(odict([('route', route), ('content', stuff)])) src = ['citizen', other.local.name, None] dst = ['mayor', main.local.name, None] route = odict([('src', src), ('dst', dst)]) stuff = "This is my reply." others = [] others.append(odict([('route', route), ('content', stuff)])) self.messageMainOther(main, other, mains, others, duration=1.0) self.assertEqual(len(main.remotes), 1) self.assertTrue('other' in main.nameRemotes) self.assertEqual(len(other.remotes), 1) self.assertTrue('main' in other.nameRemotes) self.assertNotEqual(main.nameRemotes['other'].sid, 0) self.assertNotEqual(other.nameRemotes['main'].sid, 0) self.assertEqual(main.nameRemotes['other'].rsid, other.nameRemotes['main'].sid) self.assertEqual(other.nameRemotes['main'].rsid, main.nameRemotes['other'].sid) #now close down make new stacks main.server.close() other.server.close() main = self.createLaneStack(data=mainData, main=True) other = self.createLaneStack(data=otherData) main.addRemote(yarding.RemoteYard(stack=main, ha=other.ha)) self.assertTrue('other' in main.nameRemotes) other.addRemote(yarding.RemoteYard(stack=other, ha=main.ha)) self.assertTrue('main' in other.nameRemotes) self.assertEqual(len(main.remotes), 1) self.assertEqual(len(other.remotes), 1) self.assertNotEqual(main.nameRemotes['other'].sid, 0) self.assertNotEqual(other.nameRemotes['main'].sid, 0) self.assertEqual(main.nameRemotes['other'].rsid, 0) self.assertEqual(other.nameRemotes['main'].rsid, 0) self.messageMainOther(main, other, mains, others, duration=1.0) self.assertEqual(main.nameRemotes['other'].rsid, other.nameRemotes['main'].sid) self.assertEqual(other.nameRemotes['main'].rsid, main.nameRemotes['other'].sid) #now close down make new stacks main.server.close() other.server.close() main = self.createLaneStack(data=mainData, main=True) other = self.createLaneStack(data=otherData) main.addRemote(yarding.RemoteYard(stack=main, ha=other.ha)) self.assertTrue('other' in main.nameRemotes) other.addRemote(yarding.RemoteYard(stack=other, ha=main.ha)) self.assertTrue('main' in other.nameRemotes) self.assertEqual(len(main.remotes), 1) self.assertEqual(len(other.remotes), 1) self.assertNotEqual(main.nameRemotes['other'].sid, 0) self.assertNotEqual(other.nameRemotes['main'].sid, 0) self.assertEqual(main.nameRemotes['other'].rsid, 0) self.assertEqual(other.nameRemotes['main'].rsid, 0) # now send paginated messages src = ['mayor', main.local.name, None] # (house, yard, queue) dst = ['citizen', other.local.name, None] route = odict([('src', src), ('dst', dst)]) stuff = ["Do as I say."] for i in range(10000): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) mains = [] mains.append(odict([('route', route), ('content', stuff)])) src = ['citizen', other.local.name, None] dst = ['mayor', main.local.name, None] route = odict([('src', src), ('dst', dst)]) stuff = ["As you wish."] for i in range(10000): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) others = [] others.append(odict([('route', route), ('content', stuff)])) self.messageMainOther(main, other, mains, others, duration=1.0) self.assertEqual(main.nameRemotes['other'].rsid, other.nameRemotes['main'].sid) self.assertEqual(other.nameRemotes['main'].rsid, main.nameRemotes['other'].sid) #now close down make new stacks send page at a time main.server.close() other.server.close() main = self.createLaneStack(data=mainData, main=True) other = self.createLaneStack(data=otherData) main.addRemote(yarding.RemoteYard(stack=main, ha=other.ha)) self.assertTrue('other' in main.nameRemotes) other.addRemote(yarding.RemoteYard(stack=other, ha=main.ha)) self.assertTrue('main' in other.nameRemotes) self.assertEqual(len(main.remotes), 1) self.assertEqual(len(other.remotes), 1) self.assertNotEqual(main.nameRemotes['other'].sid, 0) self.assertNotEqual(other.nameRemotes['main'].sid, 0) self.assertEqual(main.nameRemotes['other'].rsid, 0) self.assertEqual(other.nameRemotes['main'].rsid, 0) for msg in mains: main.transmit(msg, uid=main.fetchUidByName(other.local.name)) for msg in others: other.transmit(msg, uid=other.fetchUidByName(main.local.name)) self.assertEqual(len(main.txMsgs), 1) self.assertEqual(len(other.txMsgs), 1) self.assertEqual(len(main.nameRemotes['other'].books), 0) self.assertEqual(len(other.nameRemotes['main'].books), 0) self.assertEqual(len(main.rxMsgs), 0) self.assertEqual(len(other.rxMsgs), 0) # Now only send and receive one page to/from each side self.serviceOneAll(main, other) self.assertEqual(len(main.txMsgs), 0) self.assertEqual(len(other.txMsgs), 0) self.assertEqual(len(main.txes), 1) self.assertEqual(len(other.txes), 1) self.assertEqual(len(main.nameRemotes['other'].books), 1) self.assertEqual(len(other.nameRemotes['main'].books), 1) self.assertEqual(len(main.rxMsgs), 0) self.assertEqual(len(other.rxMsgs), 0) self.assertEqual(main.nameRemotes['other'].rsid, other.nameRemotes['main'].sid) self.assertEqual(other.nameRemotes['main'].rsid, main.nameRemotes['other'].sid) # save sids mainSid = main.nameRemotes['other'].sid otherSid = other.nameRemotes['main'].sid #now close down one side only, make new stack main.server.close() main = self.createLaneStack(data=mainData, main=True) main.addRemote(yarding.RemoteYard(stack=main, ha=other.ha)) self.assertEqual(len(main.remotes), 1) self.assertEqual(len(other.remotes), 1) self.assertNotEqual(main.nameRemotes['other'].sid, mainSid) self.assertEqual(other.nameRemotes['main'].sid, otherSid) self.assertEqual(main.nameRemotes['other'].rsid, 0) self.assertEqual(other.nameRemotes['main'].rsid, mainSid) self.assertEqual(len(main.txes), 0) self.assertEqual(len(other.txes), 1) self.assertEqual(len(main.nameRemotes['other'].books), 0) self.assertEqual(len(other.nameRemotes['main'].books), 1) self.assertEqual(len(main.rxMsgs), 0) self.assertEqual(len(other.rxMsgs), 0) # Now remaining page from other (there should be no pages from main) self.serviceOneAll(main, other) self.assertEqual(main.nameRemotes['other'].rsid, other.nameRemotes['main'].sid) self.assertNotEqual(other.nameRemotes['main'].rsid, main.nameRemotes['other'].sid) self.assertEqual(len(main.txes), 0) self.assertEqual(len(other.txes), 0) self.assertEqual(len(main.nameRemotes['other'].books), 0) self.assertEqual(len(other.nameRemotes['main'].books), 1) self.assertEqual(len(main.rxMsgs), 0) self.assertEqual(len(other.rxMsgs), 0) self.assertEqual(main.stats['missed_page'], 1) #send a new message from main and reap stale book from other for msg in mains: main.transmit(msg, uid=main.fetchUidByName(other.local.name)) self.serviceMainOther(main, other, duration=1.0) self.assertEqual(main.nameRemotes['other'].rsid, other.nameRemotes['main'].sid) self.assertEqual(other.nameRemotes['main'].rsid, main.nameRemotes['other'].sid) self.assertEqual(len(main.txes), 0) self.assertEqual(len(other.txes), 0) self.assertEqual(len(main.nameRemotes['other'].books), 0) self.assertEqual(len(other.nameRemotes['main'].books), 0) self.assertEqual(len(main.rxMsgs), 0) self.assertEqual(len(main.rxMsgs), 0) self.assertEqual(len(other.rxMsgs), 1) self.assertEqual(other.stats['stale_book'], 1) self.assertEqual(len(other.rxMsgs), len(mains)) for i, duple in enumerate(other.rxMsgs): console.terse("Yard '{0}' rxed:\n'{1}'\n".format(other.local.name, duple)) self.assertDictEqual(mains[i], duple[0]) # setup to test reset sid numbering by sending single pages to create stale books other.rxMsgs.pop() for msg in mains: main.transmit(msg, uid=main.fetchUidByName(other.local.name)) for msg in others: other.transmit(msg, uid=other.fetchUidByName(main.local.name)) self.serviceOneAll(main, other) self.assertEqual(main.nameRemotes['other'].rsid, other.nameRemotes['main'].sid) self.assertEqual(other.nameRemotes['main'].rsid, main.nameRemotes['other'].sid) self.assertEqual(len(main.txes), 1) self.assertEqual(len(other.txes), 1) self.assertEqual(len(main.nameRemotes['other'].books), 1) self.assertEqual(len(other.nameRemotes['main'].books), 1) self.assertEqual(len(main.rxMsgs), 0) self.assertEqual(len(other.rxMsgs), 0) # simulate restart that loses msg in queue main.txes.pop() other.txes.pop() src = ['mayor', main.local.name, None] # (house, yard, queue) dst = ['citizen', other.local.name, None] route = odict([('src', src), ('dst', dst)]) stuff = "This is my command" mains = [] mains.append(odict([('route', route), ('content', stuff)])) src = ['citizen', other.local.name, None] dst = ['mayor', main.local.name, None] route = odict([('src', src), ('dst', dst)]) stuff = "This is my reply." others = [] others.append(odict([('route', route), ('content', stuff)])) mainSid = main.local.nextSid() otherSid = other.local.nextSid() main.nameRemotes['other'].sid = mainSid other.nameRemotes['main'].sid = otherSid for msg in mains: main.transmit(msg, uid=main.fetchUidByName(other.local.name)) for msg in others: other.transmit(msg, uid=other.fetchUidByName(main.local.name)) self.serviceOneAll(main, other) self.assertEqual(main.nameRemotes['other'].sid, mainSid) self.assertEqual(other.nameRemotes['main'].sid, otherSid) self.assertEqual(main.nameRemotes['other'].rsid, otherSid) self.assertEqual(other.nameRemotes['main'].rsid, mainSid) self.assertEqual(len(main.txes), 0) self.assertEqual(len(other.txes), 0) self.assertEqual(len(main.nameRemotes['other'].books), 0) self.assertEqual(len(other.nameRemotes['main'].books), 0) self.assertEqual(len(main.rxMsgs), 1) self.assertEqual(len(other.rxMsgs), 1) self.assertEqual(main.stats['stale_book'], 1) self.assertEqual(other.stats['stale_book'], 2) main.server.close() other.server.close()
class BasicTestCase(unittest.TestCase): """""" def setUp(self): self.store = Store(stamp=0.0) self.timer = StoreTimer(store=self.store, duration=1.0) self.baseDirpath=tempfile.mkdtemp(prefix="raet", suffix="base", dir=TEMPDIR) stacking.RoadStack.Bk = raeting.BodyKind.json.value #main stack mainName = "main" mainDirpath = os.path.join(self.baseDirpath, 'road', 'keep', mainName) signer = nacling.Signer() mainSignKeyHex = signer.keyhex privateer = nacling.Privateer() mainPriKeyHex = privateer.keyhex #other stack otherName = "other" otherDirpath = os.path.join(self.baseDirpath, 'road', 'keep', otherName) signer = nacling.Signer() otherSignKeyHex = signer.keyhex privateer = nacling.Privateer() otherPriKeyHex = privateer.keyhex keeping.clearAllKeep(mainDirpath) keeping.clearAllKeep(otherDirpath) self.main = stacking.RoadStack(store=self.store, name=mainName, main=True, auto=raeting.AutoMode.once.value, sigkey=mainSignKeyHex, prikey=mainPriKeyHex, dirpath=mainDirpath, ) self.other = stacking.RoadStack(store=self.store, name=otherName, auto=raeting.AutoMode.once.value, ha=("", raeting.RAET_TEST_PORT), sigkey=otherSignKeyHex, prikey=otherPriKeyHex, dirpath=otherDirpath, ) def tearDown(self): self.main.server.close() self.other.server.close() self.main.clearAllDir() self.other.clearAllDir() if os.path.exists(self.baseDirpath): shutil.rmtree(self.baseDirpath) def join(self, timeout=None): ''' Utility method to do join. Call from test method. ''' console.terse("\nJoin Transaction **************\n") if not self.other.remotes: self.other.addRemote(estating.RemoteEstate(stack=self.other, #name=self.main.local.name, fuid=0, # vacuous join sid=0, # always 0 for join ha=self.main.local.ha) ) self.other.join(timeout=timeout) self.service() def allow(self): ''' Utility method to do allow. Call from test method. ''' console.terse("\nAllow Transaction **************\n") self.other.allow() self.service() def alive(self, initiator, correspondent): ''' Utility method to do alive. Call from test method. ''' console.terse("\nAlive Transaction **************\n") initiator.alive() self.service() def service(self, duration=1.0, real=True): ''' Utility method to service queues. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: self.other.serviceAll() self.main.serviceAll() if not (self.main.transactions or self.other.transactions): break self.store.advanceStamp(0.1) if real: time.sleep(0.1) def serviceOther(self, duration=1.0, real=True): ''' Utility method to only service other queues. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: self.other.serviceAll() if not (self.other.transactions): break self.store.advanceStamp(0.1) if real: time.sleep(0.1) def serviceMain(self, duration=1.0, real=True): ''' Utility method to only service main queues. Call from test method. ''' self.timer.restart(duration=duration) while not self.timer.expired: self.main.serviceAll() if not (self.main.transactions): break self.store.advanceStamp(0.1) if real: time.sleep(0.1) def bootstrap(self, bk=raeting.BodyKind.json.value): ''' Initialize main on port 7530 with uid of 1 other on port 7531 with uid of 1 Complete main joined and allowed other joined and allowed ''' stacking.RoadStack.Bk = bk self.assertEqual(self.main.name, 'main') self.assertEqual(self.main.local.name, 'main') self.assertEqual(self.main.ha, ("0.0.0.0", raeting.RAET_PORT)) self.assertEqual(self.other.name, 'other') self.assertEqual(self.other.local.name, 'other') self.assertEqual(self.other.ha, ("0.0.0.0", raeting.RAET_TEST_PORT)) self.join() console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(self.main.local.uid, 1) self.assertEqual(self.main.name, 'main') self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(remote.name, 'other') self.assertEqual(remote.uid, 2) self.assertEqual(remote.uid, remote.nuid) self.assertEqual(remote.fuid, 2) self.assertTrue(2 in self.main.remotes) self.assertTrue(remote.uid in self.main.remotes) self.assertTrue(len(self.main.remotes), 1) self.assertTrue(len(self.main.nameRemotes), 1) self.assertEqual(len(remote.transactions), 0) self.assertTrue('other' in self.main.nameRemotes) self.assertIs(self.main.nameRemotes[remote.name], remote) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.main.name, self.main.local.name, remote.name, remote.joined)) console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(self.other.local.uid, 1) self.assertEqual(self.other.name, 'other') self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(remote.name, 'main') self.assertEqual(remote.uid, 2) self.assertEqual(remote.uid, remote.nuid) self.assertEqual(remote.fuid, 2) self.assertTrue(2 in self.other.remotes) self.assertTrue(remote.uid in self.other.remotes) self.assertTrue(len(self.other.remotes), 1) self.assertTrue(len(self.other.nameRemotes), 1) self.assertEqual(len(remote.transactions), 0) self.assertTrue('main' in self.other.nameRemotes) self.assertIs(self.other.nameRemotes[remote.name], remote) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.other.name, self.other.local.name, remote.name, remote.joined)) self.allow() console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.allowed) self.assertEqual(len(remote.transactions), 0) console.terse("Stack '{0}' estate name '{1}' allowd with '{2}' = {3}\n".format( self.main.name, self.main.local.name, remote.name, remote.allowed)) console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.allowed) self.assertEqual(len(remote.transactions), 0) console.terse("Stack '{0}' estate name '{1}' allowed with '{2}' = {3}\n".format( self.other.name, self.other.local.name, remote.name, remote.allowed)) console.terse("\nMessage: other to main *********\n") body = odict(what="This is a message to the main estate. How are you", extra="I am fine.") self.other.txMsgs.append((body, self.other.remotes.values()[0].fuid, None)) #self.other.message(body=body, deid=self.main.local.uid) self.service() console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(len(self.main.transactions), 0) for msg, name in self.main.rxMsgs: console.terse("Estate '{0}' rxed:\n'{1}'\n".format(self.main.local.name, msg)) self.assertDictEqual(body, self.main.rxMsgs[0][0]) console.terse("\nMessage: main to other *********\n") body = odict(what="This is a message to the other estate. Get to Work", extra="Fix the fence.") self.main.txMsgs.append((body, self.main.remotes.values()[0].fuid, None)) #self.main.message(body=body, deid=self.other.local.uid) self.service() console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(len(self.other.transactions), 0) for msg, name in self.other.rxMsgs: console.terse("Estate '{0}' rxed:\n'{1}'\n".format(self.other.local.name, msg)) self.assertDictEqual(body, self.other.rxMsgs[0][0]) def bidirectional(self, bk=raeting.BodyKind.json.value, mains=None, others=None, duration=3.0,): ''' Initialize main on port 7530 with uid of 1 other on port 7531 with uid of 0 Complete main uid of 1 joined and allowed other uid of 2 joined and allowed ''' stacking.RoadStack.Bk = bk mains = mains or [] other = others or [] self.join() self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.joined) self.allow() self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.allowed) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.allowed) console.terse("\nMessages Bidirectional *********\n") for msg in mains: self.main.transmit(msg) for msg in others: self.other.transmit(msg) self.service(duration=duration) console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(len(self.main.transactions), 0) self.assertEqual(len(others), len(self.main.rxMsgs)) for i, duple in enumerate(self.main.rxMsgs): console.terse("Estate '{0}' rxed:\n'{1}'\n".format(self.main.local.name, duple)) self.assertDictEqual(others[i], duple[0]) console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(len(self.other.transactions), 0) self.assertEqual(len(mains), len(self.other.rxMsgs)) for i, duple in enumerate(self.other.rxMsgs): console.terse("Estate '{0}' rxed:\n'{1}'\n".format(self.other.local.name, duple)) self.assertDictEqual(mains[i], duple[0]) def testBootstrapJson(self): ''' Test join allow message transactions with JSON Serialization of body ''' console.terse("{0}\n".format(self.testBootstrapJson.__doc__)) self.bootstrap(bk=raeting.BodyKind.json.value) def testBootstrapMsgpack(self): ''' Test join allow message transactions with MsgPack Serialization of body ''' console.terse("{0}\n".format(self.testBootstrapMsgpack.__doc__)) self.bootstrap(bk=raeting.BodyKind.msgpack.value) def testMsgBothwaysJson(self): ''' Test message transactions ''' console.terse("{0}\n".format(self.testMsgBothwaysJson.__doc__)) others = [] others.append(odict(house="Mama mia1", queue="fix me")) others.append(odict(house="Mama mia2", queue="help me")) others.append(odict(house="Mama mia3", queue="stop me")) others.append(odict(house="Mama mia4", queue="run me")) mains = [] mains.append(odict(house="Papa pia1", queue="fix me")) mains.append(odict(house="Papa pia2", queue="help me")) mains.append(odict(house="Papa pia3", queue="stop me")) mains.append(odict(house="Papa pia4", queue="run me")) self.bidirectional(bk=raeting.BodyKind.json.value, mains=mains, others=others) def testMsgBothwaysMsgpack(self): ''' Test message transactions ''' console.terse("{0}\n".format(self.testMsgBothwaysMsgpack.__doc__)) others = [] others.append(odict(house="Mama mia1", queue="fix me")) others.append(odict(house="Mama mia2", queue="help me")) others.append(odict(house="Mama mia3", queue="stop me")) others.append(odict(house="Mama mia4", queue="run me")) mains = [] mains.append(odict(house="Papa pia1", queue="fix me")) mains.append(odict(house="Papa pia2", queue="help me")) mains.append(odict(house="Papa pia3", queue="stop me")) mains.append(odict(house="Papa pia4", queue="run me")) self.bidirectional(bk=raeting.BodyKind.msgpack.value, mains=mains, others=others) def testMsgVeritive(self): ''' Test message transactions where one is not veritive ''' console.terse("{0}\n".format(self.testMsgVeritive.__doc__)) others = [] others.append(odict(house="Mama mia1", queue="fix me")) others.append(odict(house="Mama mia2", queue="help me")) others.append(odict(house="Mama mia3", queue="stop me")) others.append(odict(house="Mama mia4", queue="run me")) mains = [] mains.append(odict(house="Papa pia1", queue="fix me")) mains.append(odict(house="Papa pia2", queue="help me")) mains.append(odict(house="Papa pia3", queue="stop me")) mains.append(odict(house="Papa pia4", queue="run me")) self.assertIs(self.main.veritive, True) self.assertIs(self.other.veritive, True) self.bootstrap() self.assertEqual(len(self.main.transactions), 0) self.assertEqual(len(self.main.rxMsgs), 1) self.main.rxMsgs.popleft() self.assertEqual(len(self.other.transactions), 0) self.assertEqual(len(self.other.rxMsgs), 1) self.other.rxMsgs.popleft() self.main.Fk = raeting.FootKind.nada.value # main does not sign its messages msg = odict(house="Mama mia1", queue="fix me") self.main.transmit(msg) msg = odict(house="Papa pia1", queue="fix me") self.other.transmit(msg) self.service(duration=0.3) # other will reject main's message because not signed self.assertEqual(len(self.main.transactions), 1) self.assertEqual(len(self.main.rxMsgs), 1) self.main.rxMsgs.popleft() self.assertEqual(len(self.other.transactions), 0) self.assertEqual(len(self.other.rxMsgs), 0) self.assertIn('parsing_outer_error', self.other.stats) self.assertEqual(self.other.stats['parsing_outer_error'], 1) remote = self.main.remotes.values()[0] remote.transactions = odict() # clear transactions self.assertEqual(len(self.main.transactions), 0) # no initated transaction self.service(duration=0.25) # consume packet in UDP buffer self.other.veritive = False # Other will accept unsigned messages self.assertIs(self.other.veritive, False) msg = odict(house="Mama mia1", queue="fix me") self.main.transmit(msg) msg = odict(house="Papa pia1", queue="fix me") self.other.transmit(msg) self.service(duration=0.3) # other will accept main's unsigned message but other's done ack will not # be accepted by main because it won't be signed and main's veritive is True # so mains transaction does not complete self.assertEqual(len(self.main.transactions), 1) self.assertEqual(len(self.main.rxMsgs), 1) self.main.rxMsgs.popleft() self.assertEqual(len(self.other.transactions), 0) self.assertEqual(len(self.other.rxMsgs), 1) self.other.rxMsgs.popleft() self.assertIn('parsing_outer_error', self.main.stats) self.assertEqual(self.main.stats['parsing_outer_error'], 1) remote = self.main.remotes.values()[0] remote.transactions = odict() # clear transactions self.assertEqual(len(self.main.transactions), 0) # no initated transaction self.service(duration=0.5) # consume packets in UDP self.main.veritive = False # main will accept unsigned messages self.assertIs(self.main.veritive, False) msg = odict(house="Mama mia1", queue="fix me") self.main.transmit(msg) msg = odict(house="Papa pia1", queue="fix me") self.other.transmit(msg) self.service(duration=0.3) # main will now complete its transaction because it will accept unsigned acks # other will accept unsigned but generates signed each message completes self.assertEqual(len(self.main.transactions), 0) self.assertEqual(len(self.main.rxMsgs), 1) self.main.rxMsgs.popleft() self.assertEqual(len(self.other.transactions), 0) self.assertEqual(len(self.other.rxMsgs), 1) self.other.rxMsgs.popleft() def testSegmentedJson(self): ''' Test segmented message transactions ''' console.terse("{0}\n".format(self.testSegmentedJson.__doc__)) stuff = [] for i in range(300): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) others = [] mains = [] others.append(odict(house="Snake eyes", queue="near stuff", stuff=stuff)) mains.append(odict(house="Craps", queue="far stuff", stuff=stuff)) bloat = [] for i in range(300): bloat.append(str(i).rjust(100, " ")) bloat = "".join(bloat) others.append(odict(house="Other", queue="big stuff", bloat=bloat)) mains.append(odict(house="Main", queue="gig stuff", bloat=bloat)) self.bidirectional(bk=raeting.BodyKind.json.value, mains=mains, others=others, duration=20.0) def testSegmentedMsgpack(self): ''' Test segmented message transactions ''' console.terse("{0}\n".format(self.testSegmentedMsgpack.__doc__)) stuff = [] for i in range(300): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) others = [] mains = [] others.append(odict(house="Snake eyes", queue="near stuff", stuff=stuff)) mains.append(odict(house="Craps", queue="far stuff", stuff=stuff)) bloat = [] for i in range(300): bloat.append(str(i).rjust(100, " ")) bloat = "".join(bloat) others.append(odict(house="Other", queue="big stuff", bloat=bloat)) mains.append(odict(house="Main", queue="gig stuff", bloat=bloat)) self.bidirectional(bk=raeting.BodyKind.msgpack.value, mains=mains, others=others, duration=20.0) def testSegmentedJsonBurst(self): ''' Test segmented message transactions with burst count limiting ''' console.terse("{0}\n".format(self.testSegmentedJsonBurst.__doc__)) stuff = [] for i in range(300): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) others = [] mains = [] others.append(odict(house="Snake eyes", queue="near stuff", stuff=stuff)) mains.append(odict(house="Craps", queue="far stuff", stuff=stuff)) bloat = [] for i in range(300): bloat.append(str(i).rjust(100, " ")) bloat = "".join(bloat) others.append(odict(house="Other", queue="big stuff", bloat=bloat)) mains.append(odict(house="Main", queue="gig stuff", bloat=bloat)) stacking.RoadStack.BurstSize = 16 self.assertEqual(stacking.RoadStack.BurstSize, 16) self.bidirectional(bk=raeting.BodyKind.json.value, mains=mains, others=others, duration=20.0) stacking.RoadStack.BurstSize = 0 self.assertEqual(stacking.RoadStack.BurstSize, 0) def testSegmentedMsgpackBurst(self): ''' Test segmented message transactions with burst count limiting ''' console.terse("{0}\n".format(self.testSegmentedMsgpackBurst.__doc__)) stuff = [] for i in range(300): stuff.append(str(i).rjust(10, " ")) stuff = "".join(stuff) others = [] mains = [] others.append(odict(house="Snake eyes", queue="near stuff", stuff=stuff)) mains.append(odict(house="Craps", queue="far stuff", stuff=stuff)) bloat = [] for i in range(300): bloat.append(str(i).rjust(100, " ")) bloat = "".join(bloat) others.append(odict(house="Other", queue="big stuff", bloat=bloat)) mains.append(odict(house="Main", queue="gig stuff", bloat=bloat)) stacking.RoadStack.BurstSize = 16 self.assertEqual(stacking.RoadStack.BurstSize, 16) self.bidirectional(bk=raeting.BodyKind.msgpack.value, mains=mains, others=others, duration=20.0) stacking.RoadStack.BurstSize = 0 self.assertEqual(stacking.RoadStack.BurstSize, 0) def testJoinForever(self): ''' Test other joining with timeout set to 0.0 and default ''' console.terse("{0}\n".format(self.testJoinForever.__doc__)) self.other.addRemote(estating.RemoteEstate(stack=self.other, fuid=0, # vacuous join sid=0, # always 0 for join ha=self.main.local.ha)) self.other.join(timeout=0.0) #attempt to join forever with timeout 0.0 self.serviceOther(duration=20.0, real=False) # only service other so no response console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(self.main.local.uid, 1) self.assertEqual(self.main.name, 'main') self.assertEqual(len(self.main.transactions), 0) self.assertEqual(len(self.main.remotes), 0) console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(self.other.local.uid, 1) self.assertEqual(self.other.name, 'other') self.assertEqual(len(self.other.transactions), 1) remote = self.other.remotes.values()[0] self.assertIs(remote.joined, None) self.assertEqual(remote.uid, 2) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.other.name, self.other.local.name, remote.name, remote.joined)) console.terse("{0} Stats\n".format(self.main.name)) for key, val in self.main.stats.items(): console.terse(" {0}={1}\n".format(key, val)) self.assertEqual(len(self.main.stats), 0) console.terse("{0} Stats\n".format(self.other.name)) for key, val in self.other.stats.items(): console.terse(" {0}={1}\n".format(key, val)) self.assertEqual(self.other.stats.get('joiner_tx_join_redo'), 6) # Now allow join to complete self.service() console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(self.main.local.uid, 1) self.assertEqual(self.main.name, 'main') self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(remote.uid, 2) self.assertTrue(2 in self.main.remotes) self.assertTrue(len(self.main.remotes), 1) self.assertTrue(len(self.main.nameRemotes), 1) self.assertEqual(remote.name, 'other') self.assertTrue('other' in self.main.nameRemotes) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.main.name, self.main.local.name, remote.name, remote.joined)) console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(self.other.local.uid, 1) self.assertEqual(self.other.name, 'other') self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(remote.uid, 2) self.assertTrue(2 in self.other.remotes) self.assertTrue(len(self.other.remotes), 1) self.assertTrue(len(self.other.nameRemotes), 1) self.assertEqual(remote.name, 'main') self.assertTrue('main' in self.other.nameRemotes) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.other.name, self.other.local.name, remote.name, remote.joined)) # Now try again with existing remote data self.other.join(timeout=0.0) #attempt to join forever with timeout 0.0 self.serviceOther(duration=20.0, real=False) # only service other so no response # main will still have join results from previous join transaction console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(self.main.local.uid, 1) self.assertEqual(self.main.name, 'main') self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(remote.uid, 2) self.assertTrue(2 in self.main.remotes) self.assertTrue(len(self.main.remotes), 1) self.assertTrue(len(self.main.nameRemotes), 1) self.assertEqual(remote.name, 'other') self.assertTrue('other' in self.main.nameRemotes) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.main.name, self.main.local.name, remote.name, remote.joined)) # Other will have outstanding join transaction console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(self.other.local.uid, 1) self.assertEqual(self.other.name, 'other') self.assertEqual(len(self.other.transactions), 1) remote = self.other.remotes.values()[0] self.assertIs(remote.joined, None) self.assertEqual(remote.uid, 2) self.assertTrue(2 in self.other.remotes) self.assertTrue(len(self.other.remotes), 1) self.assertTrue(len(self.other.nameRemotes), 1) self.assertEqual(remote.name, 'main') self.assertTrue('main' in self.other.nameRemotes) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.other.name, self.other.local.name, remote.name, remote.joined)) console.terse("{0} Stats\n".format(self.main.name)) for key, val in self.main.stats.items(): console.terse(" {0}={1}\n".format(key, val)) self.assertEqual(self.main.stats.get('join_correspond_complete'), 1) console.terse("{0} Stats\n".format(self.other.name)) for key, val in self.other.stats.items(): console.terse(" {0}={1}\n".format(key, val)) self.assertEqual(self.other.stats.get('joiner_tx_join_redo'), 12) self.assertEqual(self.other.stats.get('join_initiate_complete'), 1) # Now allow join to complete self.service() console.terse("\nStack '{0}' uid= {1}\n".format(self.main.name, self.main.local.uid)) self.assertEqual(self.main.local.uid, 1) self.assertEqual(self.main.name, 'main') self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(remote.uid, 2) self.assertTrue(2 in self.main.remotes) self.assertTrue(len(self.main.remotes), 1) self.assertTrue(len(self.main.nameRemotes), 1) self.assertEqual(remote.name, 'other') self.assertTrue('other' in self.main.nameRemotes) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.main.name, self.main.local.name, remote.name, remote.joined)) console.terse("\nStack '{0}' uid= {1}\n".format(self.other.name, self.other.local.uid)) self.assertEqual(self.other.local.uid, 1) self.assertEqual(self.other.name, 'other') self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(remote.uid, 2) self.assertTrue(2 in self.other.remotes) self.assertTrue(len(self.other.remotes), 1) self.assertTrue(len(self.other.nameRemotes), 1) self.assertEqual(remote.name, 'main') self.assertTrue('main' in self.other.nameRemotes) console.terse("Stack '{0}' estate name '{1}' joined with '{2}' = {3}\n".format( self.other.name, self.other.local.name, remote.name, remote.joined)) def testStaleNack(self): ''' Test stale nack ''' console.terse("{0}\n".format(self.testStaleNack.__doc__)) self.join() self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.joined) self.allow() self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.allowed) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.allowed) console.terse("\nMessage transaction *********\n") body = odict(what="This is a message to the main estate. How are you", extra="I am fine.") self.other.txMsgs.append((body, self.other.remotes.values()[0].fuid, None)) self.timer.restart(duration=1.0) while not self.timer.expired: self.other.serviceAllTx() # transmit but leave receives in socket buffer self.main.serviceAllRx() # receive but leave transmits in queue self.store.advanceStamp(0.1) time.sleep(0.1) self.assertEqual(len(self.main.transactions), 0) #completed self.assertEqual(len(self.other.transactions), 1) # waiting for ack remote = self.other.remotes.values()[0] remote.transactions = odict() #clear transactions so RX is stale correspondent self.assertEqual(len(self.other.transactions), 0) # no initated transaction self.timer.restart(duration=2.0) while not self.timer.expired: self.main.serviceAll() # transmit stale ack self.other.serviceAll() # recieve ack self.store.advanceStamp(0.1) time.sleep(0.1) self.assertEqual(len(self.main.transactions), 0) self.assertEqual(len(self.other.transactions), 0) print("{0} Stats".format(self.main.name)) for key, val in self.main.stats.items(): print(" {0}={1}".format(key, val)) print() print("{0} Stats".format(self.other.name)) for key, val in self.other.stats.items(): print(" {0}={1}".format(key, val)) print() self.assertTrue(self.other.stats.get('stale_correspondent_attempt') >= 1) self.assertTrue(self.other.stats.get('stale_correspondent_nack') >= 1) self.assertTrue(self.main.stats.get('messengent_correspond_complete') >= 1) self.assertTrue(self.main.stats.get('stale_packet') >= 1) def testBasicAlive(self): ''' Test basic alive transaction ''' console.terse("{0}\n".format(self.testBasicAlive.__doc__)) self.join() self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.joined) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.joined) self.allow() self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.allowed) self.assertTrue(remote.alived) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.allowed) self.assertTrue(remote.alived) console.terse("\nAlive Other to Main *********\n") otherRemote = self.main.remotes.values()[0] mainRemote = self.other.remotes.values()[0] otherRemote.alived = None mainRemote.alived = None self.alive(self.other, self.main) self.assertEqual(len(self.main.transactions), 0) self.assertTrue(otherRemote.alived) self.assertEqual(len(self.other.transactions), 0) self.assertTrue(mainRemote.alived) console.terse("\nAlive Main to Other *********\n") self.alive(self.main, self.other) self.assertEqual(len(self.main.transactions), 0) remote = self.main.remotes.values()[0] self.assertTrue(remote.alived) self.assertEqual(len(self.other.transactions), 0) remote = self.other.remotes.values()[0] self.assertTrue(remote.alived)