Пример #1
0
    def setUp(self):
        self.store = storing.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)
Пример #2
0
    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
Пример #3
0
    def setUp(self):
        self.store = storing.Store(stamp=0.0)
        self.timer = StoreTimer(store=self.store, duration=1.0)

        self.baseDirpath = os.path.join(
            tempfile.mkdtemp(prefix="raet", suffix="base", dir='/tmp'), 'lane',
            'keep')

        # main stack
        self.main = stacking.LaneStack(name='main',
                                       yid=1,
                                       localname='main',
                                       lanename='cherry',
                                       basedirpath=self.baseDirpath,
                                       sockdirpath=self.baseDirpath)

        #other stack
        self.other = stacking.LaneStack(name='other',
                                        yid=1,
                                        localname='other',
                                        lanename='cherry',
                                        basedirpath=self.baseDirpath,
                                        sockdirpath=self.baseDirpath)
Пример #4
0
def testStackUxd(kind=raeting.packKinds.json):
    '''
    initially


    '''
    console.reinit(verbosity=console.Wordage.concise)

    stacking.LaneStack.Pk = kind

    #lord stack
    #yard0 = yarding.Yard(name='lord')
    stack0 = stacking.LaneStack(dirpath='/tmp/raet/test_stacking',
                                sockdirpath='/tmp/raet/test_stacking')

    #serf stack
    #yard1 = yarding.Yard(name='serf', yid=1)
    stack1 = stacking.LaneStack(dirpath='/tmp/raet/test_stacking',
                                sockdirpath='/tmp/raet/test_stacking')

    stack0.addRemote(yarding.RemoteYard(ha=stack1.local.ha))
    stack1.addRemote(yarding.RemoteYard(ha=stack0.local.ha))
    #stack0.addRemoteYard(stack1.local)
    #stack1.addRemoteYard(stack0.local)

    print "{0} yard name={1} ha={2}".format(stack0.name, stack0.local.name,
                                            stack0.local.ha)
    print "{0} yards=\n{1}".format(stack0.name, stack0.remotes)
    print "{0} names=\n{1}".format(stack0.name, stack0.uids)

    print "{0} yard name={1} ha={2}".format(stack1.name, stack1.local.name,
                                            stack1.local.ha)
    print "{0} yards=\n{1}".format(stack1.name, stack1.remotes)
    print "{0} names=\n{1}".format(stack1.name, stack1.uids)

    print "\n********* UXD Message lord to serf serf to lord **********"
    msg = odict(what="This is a message to the serf. Get to Work",
                extra="Fix the fence.")
    stack0.transmit(msg=msg)

    msg = odict(what="This is a message to the lord. Let me be",
                extra="Go away.")
    stack1.transmit(msg=msg)

    timer = Timer(duration=0.5)
    timer.restart()
    while not timer.expired:
        stack0.serviceAll()
        stack1.serviceAll()

    print "{0} Received Messages".format(stack0.name)
    for msg in stack0.rxMsgs:
        print msg
    print

    print "{0} Received Messages".format(stack1.name)
    for msg in stack1.rxMsgs:
        print msg
    print

    print "\n********* Multiple Messages Both Ways **********"

    stack1.transmit(odict(house="Mama mia1", queue="fix me"), None)
    stack1.transmit(odict(house="Mama mia2", queue="help me"), None)
    stack1.transmit(odict(house="Mama mia3", queue="stop me"), None)
    stack1.transmit(odict(house="Mama mia4", queue="run me"), None)

    stack0.transmit(odict(house="Papa pia1", queue="fix me"), None)
    stack0.transmit(odict(house="Papa pia2", queue="help me"), None)
    stack0.transmit(odict(house="Papa pia3", queue="stop me"), None)
    stack0.transmit(odict(house="Papa pia4", queue="run me"), None)

    #big packets
    stuff = []
    for i in range(10000):
        stuff.append(str(i).rjust(10, " "))
    stuff = "".join(stuff)

    stack1.transmit(odict(house="Mama mia1", queue="big stuff", stuff=stuff),
                    None)
    stack0.transmit(odict(house="Papa pia4", queue="gig stuff", stuff=stuff),
                    None)

    timer.restart(duration=2)
    while not timer.expired:
        stack1.serviceAll()
        stack0.serviceAll()

    print "{0} Received Messages".format(stack0.name)
    for msg in stack0.rxMsgs:
        print msg
    print

    print "{0} Received Messages".format(stack1.name)
    for msg in stack1.rxMsgs:
        print msg
    print

    src = ('minion', 'serf', None)
    dst = ('master', None, None)
    route = odict(src=src, dst=dst)
    msg = odict(route=route, stuff="Hey buddy what is up?")
    stack0.transmit(msg)

    timer.restart(duration=2)
    while not timer.expired:
        stack1.serviceAll()
        stack0.serviceAll()

    print "{0} Received Messages".format(stack0.name)
    for msg in stack0.rxMsgs:
        print msg
    print

    print "{0} Received Messages".format(stack1.name)
    for msg in stack1.rxMsgs:
        print msg
    print

    estate = 'minion1'
    #lord stack yard0
    stack0 = stacking.LaneStack(name='lord',
                                lanename='cherry',
                                dirpath='/tmp/raet/test_stacking',
                                sockdirpath='/tmp/raet/test_stacking')

    #serf stack yard1
    stack1 = stacking.LaneStack(name='serf',
                                lanename='cherry',
                                dirpath='/tmp/raet/test_stacking',
                                sockdirpath='/tmp/raet/test_stacking')

    print "Yid", yarding.Yard.Yid

    print "\n********* Attempt Auto Accept ************"
    #stack0.addRemoteYard(stack1.local)
    yard = yarding.RemoteYard(name=stack0.local.name,
                              lanename='cherry',
                              dirpath='/tmp/raet/test_stacking')
    stack1.addRemote(yard)

    print "{0} yard name={1} ha={2}".format(stack0.name, stack0.local.name,
                                            stack0.local.ha)
    print "{0} yards=\n{1}".format(stack0.name, stack0.remotes)
    print "{0} names=\n{1}".format(stack0.name, stack0.uids)

    print "{0} yard name={1} ha={2}".format(stack1.name, stack1.local.name,
                                            stack1.local.ha)
    print "{0} yards=\n{1}".format(stack1.name, stack1.remotes)
    print "{0} names=\n{1}".format(stack1.name, stack1.uids)

    print "\n********* UXD Message serf to lord **********"
    src = (estate, stack1.local.name, None)
    dst = (estate, stack0.local.name, None)
    route = odict(src=src, dst=dst)
    msg = odict(route=route, stuff="Serf to my lord. Feed me!")
    stack1.transmit(msg=msg)

    timer = Timer(duration=0.5)
    timer.restart()
    while not timer.expired:
        stack0.serviceAll()
        stack1.serviceAll()

    print "{0} Received Messages".format(stack0.name)
    for msg in stack0.rxMsgs:
        print msg
    print

    print "{0} Received Messages".format(stack1.name)
    for msg in stack1.rxMsgs:
        print msg
    print

    print "\n********* UXD Message lord to serf **********"
    src = (estate, stack0.local.name, None)
    dst = (estate, stack1.local.name, None)
    route = odict(src=src, dst=dst)
    msg = odict(route=route, stuff="Lord to serf. Feed yourself!")
    stack0.transmit(msg=msg)

    timer = Timer(duration=0.5)
    timer.restart()
    while not timer.expired:
        stack0.serviceAll()
        stack1.serviceAll()

    print "{0} Received Messages".format(stack0.name)
    for msg in stack0.rxMsgs:
        print msg
    print

    print "{0} Received Messages".format(stack1.name)
    for msg in stack1.rxMsgs:
        print msg
    print

    print "{0} yard name={1} ha={2}".format(stack0.name, stack0.local.name,
                                            stack0.local.ha)
    print "{0} yards=\n{1}".format(stack0.name, stack0.remotes)
    print "{0} names=\n{1}".format(stack0.name, stack0.uids)

    print "{0} yard name={1} ha={2}".format(stack1.name, stack1.local.name,
                                            stack1.local.ha)
    print "{0} yards=\n{1}".format(stack1.name, stack1.remotes)
    print "{0} names=\n{1}".format(stack1.name, stack1.uids)

    stack0.server.close()
    stack1.server.close()
Пример #5
0
    def testRestart(self):
        '''
        Test messaging after restart with saved data
        '''
        console.terse("{0}\n".format(self.testRestart.__doc__))

        stacking.LaneStack.Pk = raeting.packKinds.json

        mainData = self.createLaneData(name='main', yid=1, base=self.base, lanename='apple')
        keeping.clearAllKeep(mainData['dirpath'])
        main = self.createLaneStack(data=mainData, main=True)
        self.assertTrue(main.keep.dirpath.endswith('/lane/keep/main'))
        self.assertTrue(main.keep.localdirpath.endswith('/lane/keep/main/local'))
        self.assertTrue(main.keep.remotedirpath.endswith('/lane/keep/main/remote'))
        self.assertTrue(main.keep.localfilepath.endswith('/lane/keep/main/local/yard.json'))
        self.assertTrue(main.local.ha.endswith('/lane/keep/main/apple.main.uxd'))
        self.assertTrue(main.local.main)

        otherData = self.createLaneData(name='other', yid=1, base=self.base, lanename='apple')
        keeping.clearAllKeep(otherData['dirpath'])
        other = self.createLaneStack(data=otherData)
        self.assertTrue(other.keep.dirpath.endswith('/lane/keep/other'))
        self.assertTrue(other.keep.localdirpath.endswith('/lane/keep/other/local'))
        self.assertTrue(other.keep.remotedirpath.endswith('/lane/keep/other/remote'))
        self.assertTrue(other.keep.localfilepath.endswith('/lane/keep/other/local/yard.json'))
        self.assertTrue(other.local.ha.endswith('/lane/keep/other/apple.other.uxd'))

        main.addRemote(yarding.RemoteYard(stack=main, ha=other.local.ha))
        self.assertTrue('other' in main.uids)
        other.addRemote(yarding.RemoteYard(stack=other, ha=main.local.ha))
        self.assertTrue('main' in other.uids)

        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.message(main,  other, mains, others, duration=1.0)

        self.assertEqual(len(main.remotes), 1)
        self.assertTrue('other' in main.uids)
        self.assertEqual(len(other.remotes), 1)
        self.assertTrue('main' in other.uids)

        self.assertEqual(main.remotes[main.uids['other']].sid, 0)
        self.assertEqual(other.remotes[other.uids['main']].sid, 0)
        self.assertEqual(main.remotes[main.uids['other']].rsid,
                         other.remotes[other.uids['main']].sid)
        self.assertEqual(other.remotes[other.uids['main']].rsid,
                         main.remotes[main.uids['other']].sid)

        main.dumpRemotes()
        other.dumpRemotes()

        #now close down and reload data, make new stacks with saved data
        main.server.close()
        other.server.close()
        main = stacking.LaneStack(dirpath=mainData['dirpath'], store=self.store)
        other = stacking.LaneStack(dirpath=otherData['dirpath'], store=self.store)

        self.assertEqual(len(main.remotes), 1)
        self.assertTrue('other' in main.uids)
        self.assertEqual(len(other.remotes), 1)
        self.assertTrue('main' in other.uids)

        self.assertEqual(main.remotes[main.uids['other']].sid, 1)
        self.assertEqual(other.remotes[other.uids['main']].sid, 1)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 0)
        self.assertEqual(other.remotes[other.uids['main']].rsid, 0)

        self.message(main,  other, mains, others, duration=1.0)

        self.assertEqual(main.remotes[main.uids['other']].rsid,
                         other.remotes[other.uids['main']].sid)
        self.assertEqual(other.remotes[other.uids['main']].rsid,
                         main.remotes[main.uids['other']].sid)

        #now close down and reload data, make new stacks with saved data
        main.server.close()
        other.server.close()
        main = stacking.LaneStack(dirpath=mainData['dirpath'], store=self.store)
        other = stacking.LaneStack(dirpath=otherData['dirpath'], store=self.store)

        self.assertEqual(len(main.remotes), 1)
        self.assertTrue('other' in main.uids)
        self.assertEqual(len(other.remotes), 1)
        self.assertTrue('main' in other.uids)

        self.assertEqual(main.remotes[main.uids['other']].sid, 2)
        self.assertEqual(other.remotes[other.uids['main']].sid, 2)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 0)
        self.assertEqual(other.remotes[other.uids['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.message(main,  other, mains, others, duration=1.0)

        self.assertEqual(main.remotes[main.uids['other']].rsid,
                         other.remotes[other.uids['main']].sid)
        self.assertEqual(other.remotes[other.uids['main']].rsid,
                         main.remotes[main.uids['other']].sid)

        #now close down and reload data, make new stacks with saved data
        main.server.close()
        other.server.close()
        main = stacking.LaneStack(dirpath=mainData['dirpath'], store=self.store)
        other = stacking.LaneStack(dirpath=otherData['dirpath'], store=self.store)

        self.assertEqual(len(main.remotes), 1)
        self.assertTrue('other' in main.uids)
        self.assertEqual(len(other.remotes), 1)
        self.assertTrue('main' in other.uids)

        self.assertEqual(main.remotes[main.uids['other']].sid, 3)
        self.assertEqual(other.remotes[other.uids['main']].sid, 3)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 0)
        self.assertEqual(other.remotes[other.uids['main']].rsid, 0)

        for msg in mains:
            main.transmit(msg, duid=main.uids[other.local.name])
        for msg in others:
            other.transmit(msg,  duid=other.uids[main.local.name])


        self.assertEqual(len(main.txMsgs), 1)
        self.assertEqual(len(other.txMsgs), 1)
        self.assertEqual(len(main.remotes[main.uids['other']].books), 0)
        self.assertEqual(len(other.remotes[other.uids['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.remotes[main.uids['other']].books), 1)
        self.assertEqual(len(other.remotes[other.uids['main']].books), 1)
        self.assertEqual(len(main.rxMsgs), 0)
        self.assertEqual(len(other.rxMsgs), 0)

        self.assertEqual(main.remotes[main.uids['other']].rsid,
                         other.remotes[other.uids['main']].sid)
        self.assertEqual(other.remotes[other.uids['main']].rsid,
                         main.remotes[main.uids['other']].sid)

        #now close down one side only and reload data, make new stack with saved data
        main.server.close()
        main = stacking.LaneStack(dirpath=mainData['dirpath'], store=self.store)


        self.assertEqual(main.remotes[main.uids['other']].sid, 4)
        self.assertEqual(other.remotes[other.uids['main']].sid, 3)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 0)
        self.assertEqual(other.remotes[other.uids['main']].rsid, 3)
        self.assertEqual(len(main.txes), 0)
        self.assertEqual(len(other.txes), 1)
        self.assertEqual(len(main.remotes[main.uids['other']].books), 0)
        self.assertEqual(len(other.remotes[other.uids['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.remotes[main.uids['other']].sid, 4)
        self.assertEqual(other.remotes[other.uids['main']].sid, 3)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 3)
        self.assertEqual(other.remotes[other.uids['main']].rsid, 3)
        self.assertEqual(len(main.txes), 0)
        self.assertEqual(len(other.txes), 0)
        self.assertEqual(len(main.remotes[main.uids['other']].books), 0)
        self.assertEqual(len(other.remotes[other.uids['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, duid=main.uids[other.local.name])

        self.service(main, other, duration=1.0)

        self.assertEqual(main.remotes[main.uids['other']].sid, 4)
        self.assertEqual(other.remotes[other.uids['main']].sid, 3)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 3)
        self.assertEqual(other.remotes[other.uids['main']].rsid, 4)
        self.assertEqual(len(main.txes), 0)
        self.assertEqual(len(other.txes), 0)
        self.assertEqual(len(main.remotes[main.uids['other']].books), 0)
        self.assertEqual(len(other.remotes[other.uids['main']].books), 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, msg in enumerate(other.rxMsgs):
            console.terse("Yard '{0}' rxed:\n'{1}'\n".format(other.local.name, msg))
            self.assertDictEqual(mains[i], msg)


        # setup to test reset sid numbering by sending single pages to create stale books

        other.rxMsgs.pop()
        for msg in mains:
            main.transmit(msg, duid=main.uids[other.local.name])
        for msg in others:
            other.transmit(msg,  duid=other.uids[main.local.name])

        self.serviceOneAll(main, other)

        self.assertEqual(main.remotes[main.uids['other']].sid, 4)
        self.assertEqual(other.remotes[other.uids['main']].sid, 3)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 3)
        self.assertEqual(other.remotes[other.uids['main']].rsid, 4)
        self.assertEqual(len(main.txes), 1)
        self.assertEqual(len(other.txes), 1)
        self.assertEqual(len(main.remotes[main.uids['other']].books), 1)
        self.assertEqual(len(other.remotes[other.uids['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)]))

        main.remotes[main.uids['other']].sid = 0 #set to zero to reset
        other.remotes[other.uids['main']].sid = 0 #set to zero to reset
        for msg in mains:
            main.transmit(msg, duid=main.uids[other.local.name])
        for msg in others:
            other.transmit(msg,  duid=other.uids[main.local.name])

        self.serviceOneAll(main, other)

        self.assertEqual(main.remotes[main.uids['other']].sid, 0)
        self.assertEqual(other.remotes[other.uids['main']].sid, 0)
        self.assertEqual(main.remotes[main.uids['other']].rsid, 0)
        self.assertEqual(other.remotes[other.uids['main']].rsid, 0)
        self.assertEqual(len(main.txes), 0)
        self.assertEqual(len(other.txes), 0)
        self.assertEqual(len(main.remotes[main.uids['other']].books), 0)
        self.assertEqual(len(other.remotes[other.uids['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()
        main.clearLocal()
        main.clearRemoteKeeps()

        other.server.close()
        other.clearLocal()
        other.clearRemoteKeeps()
Пример #6
0
    def testBasic(self):
        '''
        Basic keep setup for stack keep persistence load and dump
        '''
        console.terse("{0}\n".format(self.testBasic.__doc__))
        mainData = self.createLaneData(name='main', yid=1, base=self.base, lanename='apple')
        keeping.clearAllKeep(mainData['dirpath'])
        stack = self.createLaneStack(data=mainData, main=True)

        console.terse("{0} keep dirpath = {1}\n".format(stack.name, stack.keep.dirpath))
        self.assertTrue(stack.keep.dirpath.endswith('/lane/keep/main'))
        self.assertTrue(stack.keep.localdirpath.endswith('/lane/keep/main/local'))
        self.assertTrue(stack.keep.remotedirpath.endswith('/lane/keep/main/remote'))
        self.assertTrue(stack.keep.localfilepath.endswith('/lane/keep/main/local/yard.json'))
        self.assertTrue(stack.local.ha.endswith('/lane/keep/main/apple.main.uxd'))

        # test round trip
        stack.clearLocal()
        stack.clearRemoteKeeps()

        stack.dumpLocal()
        stack.dumpRemotes()

        localKeepData = stack.keep.loadLocalData()
        console.terse("Local keep data = '{0}'\n".format(localKeepData))

        validLocalKeepData = odict([
                                ('uid', 1),
                                ('name', 'main'),
                                ('ha', stack.local.ha),
                                ('main', True),
                                ('sid', 0),
                                ('lanename', 'apple'),
                                ('stack', 'main'),
                                ('nyid', 1),
                                ('accept', True)
                              ])

        self.assertDictEqual(localKeepData, validLocalKeepData)
        self.assertTrue(localKeepData['ha'].endswith('lane/keep/main/apple.main.uxd'))

        remoteKeepData = stack.keep.loadAllRemoteData()
        console.terse("Remote keep data = '{0}'\n".format(remoteKeepData))
        self.assertDictEqual(remoteKeepData, {})

        # test round trip with stack methods
        stack.loadLocal()
        localKeepData = odict([
                                ('uid', stack.local.uid),
                                ('name', stack.local.name),
                                ('ha', stack.local.ha),
                                ('main', stack.local.main),
                                ('sid', stack.local.sid),
                                ('lanename', stack.local.lanename),
                                ('stack', stack.name),
                                ('nyid', stack.nyid),
                                ('accept', stack.accept),
                              ])
        self.assertDictEqual(localKeepData, validLocalKeepData)
        self.assertTrue(stack.local.ha.endswith('lane/keep/main/apple.main.uxd'))

        #stack.removeAllRemotes()
        stack.remotes = odict()
        stack.uids = odict()
        stack.loadRemotes()
        self.assertDictEqual(stack.remotes, {})

        # round trip with non empty remote data
        other1Data = self.createLaneData(name='other1',
                                         yid=0,
                                         base=self.base,
                                         lanename=stack.local.lanename)
        stack.addRemote(yarding.RemoteYard(stack=stack,
                                           name=other1Data['name'],
                                           lanename=other1Data['lanename'],
                                           dirpath=other1Data['dirpath']))

        other2Data = self.createLaneData(name='other2',
                                         yid=0,
                                         base=self.base,
                                         lanename=stack.local.lanename)
        stack.addRemote(yarding.RemoteYard(stack=stack,
                                           name=other2Data['name'],
                                           lanename=other2Data['lanename'],
                                           dirpath=other2Data['dirpath']))

        stack.dumpRemotes()
        remoteKeepData = stack.keep.loadAllRemoteData()
        console.terse("Remote keep data = '{0}'\n".format(remoteKeepData))
        validRemoteKeepData = {'2':
                                    {'uid': 2,
                                     'name': 'other1',
                                     'ha': '',
                                     'sid': 0},
                                '3':
                                    {'uid': 3,
                                     'name': 'other2',
                                     'ha': '',
                                     'sid': 0,}
                                }
        validRemoteKeepData['2']['ha'] = stack.remotes[2].ha
        validRemoteKeepData['3']['ha'] = stack.remotes[3].ha
        self.assertDictEqual(remoteKeepData, validRemoteKeepData)

        # stack method
        #convert string uid keys into int uid keys
        temp = validRemoteKeepData
        validRemoteKeepData = odict()
        for uid in temp:
            validRemoteKeepData[int(uid)] = temp[uid]

        #stack.removeAllRemotes()
        stack.remotes = odict()
        stack.uids = odict()
        stack.loadRemotes()
        remoteKeepData = odict()
        for remote in stack.remotes.values():
            remoteKeepData[remote.uid] = odict([
                                                ('uid', remote.uid),
                                                ('name', remote.name),
                                                ('ha', remote.ha),
                                                ('sid', remote.sid),
                                               ])
        self.assertDictEqual(remoteKeepData, validRemoteKeepData)
        stack.server.close()

        # bootstrap new stack from stored keepdata
        stack = stacking.LaneStack(name=mainData['name'],
                                   dirpath=mainData['dirpath'],
                                   store=self.store)
        localKeepData = odict([
                                ('uid', stack.local.uid),
                                ('name', stack.local.name),
                                ('ha', stack.local.ha),
                                ('main', stack.local.main),
                                ('sid', stack.local.sid),
                                ('lanename', stack.local.lanename),
                                ('stack', stack.name),
                                ('nyid', stack.nyid),
                                ('accept', stack.accept),
                              ])
        console.terse("Local keep data = '{0}'\n".format(localKeepData))
        self.assertDictEqual(localKeepData, validLocalKeepData)

        remoteKeepData = odict()
        for remote in stack.remotes.values():
            remoteKeepData[remote.uid] = odict([
                                                ('uid', remote.uid),
                                                ('name', remote.name),
                                                ('ha', remote.ha),
                                                ('sid', remote.sid),
                                               ])
            validRemoteKeepData[remote.uid]['sid'] += 1 # on load stack increments
        self.assertDictEqual(remoteKeepData, validRemoteKeepData)

        stack.server.close()
        stack.clearLocal()
        stack.clearRemoteKeeps()