Ticket #1636: dead-rref-test.diff

File dead-rref-test.diff, 5.0 KB (added by warner, at 2012-06-14T23:41:53Z)

same patch, plus a test

  • src/allmydata/client.py

    diff --git a/src/allmydata/client.py b/src/allmydata/client.py
    index 1e4479b..239fdc1 100644
    a b class Client(node.Node, pollmixin.PollMixin): 
    213213        sk,vk_vs = keyutil.parse_privkey(sk_vs.strip())
    214214        self.write_config("node.pubkey", vk_vs+"\n")
    215215        self._server_key = sk
     216        self.node_key_s = vk_vs
    216217
    217218    def _init_permutation_seed(self, ss):
    218219        seed = self.get_config_from_file("permutation-seed")
  • src/allmydata/interfaces.py

    diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py
    index b1c34a7..b925552 100644
    a b class IServer(IDisplayableServer): 
    444444    def start_connecting(tub, trigger_cb):
    445445        pass
    446446    def get_rref():
    447         pass
     447        """Once a server is connected, I return a RemoteReference.
     448        Before a server is connected for the first time, I return None.
     449
     450        Note that the rref I return will start producing DeadReferenceErrors
     451        once the connection is lost.
     452        """
    448453
    449454
    450455class IMutableSlotWriter(Interface):
  • src/allmydata/storage_client.py

    diff --git a/src/allmydata/storage_client.py b/src/allmydata/storage_client.py
    index 68823f0..b536c67 100644
    a b class StorageFarmBroker: 
    7777    def test_add_rref(self, serverid, rref, ann):
    7878        s = NativeStorageServer(serverid, ann.copy())
    7979        s.rref = rref
     80        s._is_connected = True
    8081        self.servers[serverid] = s
    8182
    8283    def test_add_server(self, serverid, s):
    class StorageFarmBroker: 
    129130        return frozenset(self.servers.keys())
    130131
    131132    def get_connected_servers(self):
    132         return frozenset([s for s in self.servers.values() if s.get_rref()])
     133        return frozenset([s for s in self.servers.values() if s.is_connected()])
    133134
    134135    def get_known_servers(self):
    135136        return frozenset(self.servers.values())
    class NativeStorageServer: 
    215216        self.last_loss_time = None
    216217        self.remote_host = None
    217218        self.rref = None
     219        self._is_connected = False
    218220        self._reconnector = None
    219221        self._trigger_cb = None
    220222
    class NativeStorageServer: 
    254256        return self.announcement
    255257    def get_remote_host(self):
    256258        return self.remote_host
     259    def is_connected(self):
     260        return self._is_connected
    257261    def get_last_connect_time(self):
    258262        return self.last_connect_time
    259263    def get_last_loss_time(self):
    class NativeStorageServer: 
    287291        self.last_connect_time = time.time()
    288292        self.remote_host = rref.getPeer()
    289293        self.rref = rref
     294        self._is_connected = True
    290295        rref.notifyOnDisconnect(self._lost)
    291296
    292297    def get_rref(self):
    class NativeStorageServer: 
    296301        log.msg(format="lost connection to %(name)s", name=self.get_name(),
    297302                facility="tahoe.storage_broker", umid="zbRllw")
    298303        self.last_loss_time = time.time()
    299         self.rref = None
     304        # self.rref is now stale: all callRemote()s will get a
     305        # DeadReferenceError. We leave the stale reference in place so that
     306        # uploader/downloader code (which received this IServer through
     307        # get_connected_servers() or get_servers_for_psi()) can continue to
     308        # use s.get_rref().callRemote() and not worry about it being None.
     309        self._is_connected = False
    300310        self.remote_host = None
    301311
    302312    def stop_connecting(self):
  • src/allmydata/test/test_system.py

    diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py
    index f3d618d..a9d20ea 100644
    a b class SystemTest(SystemTestMixin, RunBinTahoeMixin, unittest.TestCase): 
    18831883            return d
    18841884        d.addCallback(_got_lit_filenode)
    18851885        return d
     1886
     1887class Connections(SystemTestMixin, unittest.TestCase):
     1888    def test_rref(self):
     1889        self.basedir = "system/Connections/rref"
     1890        d = self.set_up_nodes(2)
     1891        def _start(ign):
     1892            self.c0 = self.clients[0]
     1893            for s in self.c0.storage_broker.get_connected_servers():
     1894                if "pub-"+s.get_longname() != self.c0.node_key_s:
     1895                    break
     1896            self.s1 = s # s1 is the server, not c0
     1897            self.s1_rref = s.get_rref()
     1898            self.failIfEqual(self.s1_rref, None)
     1899            self.failUnless(self.s1.is_connected())
     1900        d.addCallback(_start)
     1901
     1902        # now shut down the server
     1903        d.addCallback(lambda ign: self.clients[1].disownServiceParent())
     1904        # and wait for the client to notice
     1905        def _poll():
     1906            return len(self.c0.storage_broker.get_connected_servers()) < 2
     1907        d.addCallback(lambda ign: self.poll(_poll))
     1908
     1909        def _down(ign):
     1910            self.failIf(self.s1.is_connected())
     1911            rref = self.s1.get_rref()
     1912            self.failUnless(rref)
     1913            self.failUnlessIdentical(rref, self.s1_rref)
     1914        d.addCallback(_down)
     1915        return d