Esempio n. 1
0
    def test_remove_contact_with_cached_replacement(self):
        """
        Ensures that the removed contact is replaced by the most up-to-date
        contact in the affected k-bucket's cache.
        """
        parent_node_id = hex((2 ** 512) + 1)[2:]
        r = RoutingTable(parent_node_id)
        cache_key = (r._buckets[0].range_min, r._buckets[0].range_max)
        contact1 = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        contact2 = PeerNode(BAD_PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        r.add_contact(contact1)
        r.add_contact(contact2)
        contact2.failed_RPCs = constants.ALLOWED_RPC_FAILS
        # Add something into the cache.
        contact3 = PeerNode(PUBLIC_KEY + 'foo', self.version,
                            'netstring://192.168.0.1:9999/', 0)
        contact3.network_id = '3'
        r._replacement_cache[cache_key] = [contact3, ]
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)
        self.assertEqual(len(r._replacement_cache[cache_key]), 1)

        r.remove_contact(BAD_PUBLIC_KEY)
        self.assertEqual(len(r._buckets[0]), 2)
        self.assertEqual(contact1, r._buckets[0]._contacts[0])
        self.assertEqual(contact3, r._buckets[0]._contacts[1])
        self.assertEqual(len(r._replacement_cache[cache_key]), 0)
Esempio n. 2
0
    def test_remove_contact_with_cached_replacement(self):
        """
        Ensures that the removed contact is replaced by the most up-to-date
        contact in the affected k-bucket's cache.
        """
        parent_node_id = 'abc'
        r = RoutingTable(parent_node_id)
        contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
        contact2 = Contact('b', '192.168.0.2', 9999, self.version, 0)
        r.add_contact(contact1)
        # Contact 2 will have the wrong number of failedRPCs
        r.add_contact(contact2)
        contact2.failed_RPCs = constants.ALLOWED_RPC_FAILS
        # Add something into the cache.
        contact3 = Contact('c', '192.168.0.3', 9999, self.version, 0)
        r._replacement_cache[0] = [contact3, ]
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)
        self.assertEqual(len(r._replacement_cache[0]), 1)

        r.remove_contact('b')
        self.assertEqual(len(r._buckets[0]), 2)
        self.assertEqual(contact1, r._buckets[0]._contacts[0])
        self.assertEqual(contact3, r._buckets[0]._contacts[1])
        self.assertEqual(len(r._replacement_cache[0]), 0)
Esempio n. 3
0
    def test_remove_contact_with_not_enough_RPC_fails(self):
        """
        Ensures that the contact is not removed if it's failedRPCs counter is
        less than constants.ALLOWED_RPC_FAILS
        """
        parent_node_id = 'abc'
        r = RoutingTable(parent_node_id)
        contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
        contact2 = Contact('b', '192.168.0.2', 9999, self.version, 0)
        r.add_contact(contact1)
        r.add_contact(contact2)
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)

        r.remove_contact('b')
        self.assertEqual(len(r._buckets[0]), 2)
Esempio n. 4
0
    def test_remove_contact_with_not_enough_RPC_but_forced(self):
        """
        Ensures that the contact is removed despite it's failedRPCs counter
        being less than constants.ALLOWED_RPC_FAILS because the 'forced' flag
        is used.
        """
        parent_node_id = 'abc'
        r = RoutingTable(parent_node_id)
        contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
        contact2 = Contact('b', '192.168.0.2', 9999, self.version, 0)
        r.add_contact(contact1)
        r.add_contact(contact2)
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)

        r.remove_contact('b', forced=True)
        self.assertEqual(len(r._buckets[0]), 1)
Esempio n. 5
0
    def test_remove_contact_with_not_enough_RPC_but_forced(self):
        """
        Ensures that the contact is removed despite it's failedRPCs counter
        being less than constants.ALLOWED_RPC_FAILS because the 'forced' flag
        is used.
        """
        parent_node_id = 'deadbeef'
        r = RoutingTable(parent_node_id)
        contact1 = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        contact2 = PeerNode(BAD_PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        r.add_contact(contact1)
        r.add_contact(contact2)
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)

        r.remove_contact(BAD_PUBLIC_KEY, forced=True)
        self.assertEqual(len(r._buckets[0]), 1)
Esempio n. 6
0
    def test_remove_contact(self):
        """
        Ensures that a contact is removed, given that it's failedRPCs counter
        exceeds or is equal to constants.ALLOWED_RPC_FAILS
        """
        parent_node_id = 'abc'
        r = RoutingTable(parent_node_id)
        contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
        contact2 = Contact('b', '192.168.0.2', 9999, self.version, 0)
        r.add_contact(contact1)
        # Contact 2 will have the wrong number of failedRPCs
        r.add_contact(contact2)
        contact2.failed_RPCs = constants.ALLOWED_RPC_FAILS
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)

        r.remove_contact('b')
        self.assertEqual(len(r._buckets[0]), 1)
        self.assertEqual(contact1, r._buckets[0]._contacts[0])
Esempio n. 7
0
    def test_remove_contact_with_not_enough_RPC_fails(self):
        """
        Ensures that the contact is not removed if it's failedRPCs counter is
        less than constants.ALLOWED_RPC_FAILS
        """
        parent_node_id = 'deadbeef'
        r = RoutingTable(parent_node_id)
        contact1 = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        contact1.network_id = 'a'
        contact2 = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        contact2.network_id = 'b'
        r.add_contact(contact1)
        r.add_contact(contact2)
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)

        r.remove_contact('b')
        self.assertEqual(len(r._buckets[0]), 2)
Esempio n. 8
0
    def test_remove_contact(self):
        """
        Ensures that a contact is removed, given that it's failedRPCs counter
        exceeds or is equal to constants.ALLOWED_RPC_FAILS
        """
        parent_node_id = 'deadbeef'
        r = RoutingTable(parent_node_id)
        contact1 = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        contact2 = PeerNode(BAD_PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        r.add_contact(contact1)
        # contact2 will have the wrong number of failedRPCs
        r.add_contact(contact2)
        contact2.failed_RPCs = constants.ALLOWED_RPC_FAILS
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)

        r.remove_contact(BAD_PUBLIC_KEY)
        self.assertEqual(len(r._buckets[0]), 1)
        self.assertEqual(contact1, r._buckets[0]._contacts[0])
Esempio n. 9
0
 def test_blacklist_public_key(self):
     """
     Ensure that a contact is removed from the routing table and blacklist
     given a matching public_key.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     contact = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0)
     r.remove_contact = MagicMock()
     r._blacklist_public_key(PUBLIC_KEY)
     r.remove_contact.called_once_with(contact, True)
     self.assertIn(contact.public_key, r._blacklist)
Esempio n. 10
0
    def test_remove_contact_removes_from_replacement_cache(self):
        """
        Ensures that if a contact is signalled to be removed it is also cleared
        from the replacement_cache that would otherwise be another route for
        it to be re-added to the routing table.
        """
        parent_node_id = 'abc'
        r = RoutingTable(parent_node_id)
        contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
        contact2 = Contact('b', '192.168.0.2', 9999, self.version, 0)
        r.add_contact(contact1)
        r.add_contact(contact2)
        r._replacement_cache[0] = []
        r._replacement_cache[0].append(contact2)
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)
        self.assertEqual(len(r._replacement_cache[0]), 1)

        r.remove_contact('b', forced=True)
        self.assertEqual(len(r._buckets[0]), 1)
        self.assertNotIn(contact2, r._replacement_cache)
Esempio n. 11
0
 def test_blacklist(self):
     """
     Ensures a misbehaving peer is correctly blacklisted. The remove_contact
     method is called and the contact's id is added to the _blacklist set.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     contact = Contact('abc', '192.168.0.1', 9999, 0)
     r.remove_contact = MagicMock()
     r.blacklist(contact)
     r.remove_contact.called_once_with(contact, True)
     self.assertIn(contact.id, r._blacklist)
Esempio n. 12
0
 def test_blacklist(self):
     """
     Ensures a misbehaving peer is correctly blacklisted. The remove_contact
     method is called and the contact's public key is added to the
     _blacklist set.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     contact = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0)
     r.remove_contact = MagicMock()
     r.blacklist(contact)
     r.remove_contact.called_once_with(contact, True)
     self.assertIn(contact.public_key, r._blacklist)
Esempio n. 13
0
    def test_remove_contact_removes_from_replacement_cache(self):
        """
        Ensures that if a contact is signalled to be removed it is also cleared
        from the replacement_cache that would otherwise be another route for
        it to be re-added to the routing table.
        """
        parent_node_id = 'deadbeef'
        r = RoutingTable(parent_node_id)
        contact1 = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        contact2 = PeerNode(BAD_PUBLIC_KEY, self.version,
                            'netstring://192.168.0.1:9999/', 0)
        r.add_contact(contact1)
        r.add_contact(contact2)
        cache_key = (r._buckets[0].range_min, r._buckets[0].range_max)
        r._replacement_cache[cache_key] = []
        r._replacement_cache[cache_key].append(contact2)
        # Sanity check
        self.assertEqual(len(r._buckets[0]), 2)
        self.assertEqual(len(r._replacement_cache[cache_key]), 1)

        r.remove_contact(BAD_PUBLIC_KEY, forced=True)
        self.assertEqual(len(r._buckets[0]), 1)
        self.assertNotIn(contact2, r._replacement_cache[cache_key])
Esempio n. 14
0
 def test_remove_contact_with_unknown_contact(self):
     """
     Ensures that attempting to remove a non-existent contact results in a
     ValueError exception.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
     r.add_contact(contact1)
     # Sanity check
     self.assertEqual(len(r._buckets[0]), 1)
     result = r.remove_contact('b')
     self.assertEqual(None, result)
     self.assertEqual(len(r._buckets[0]), 1)
     self.assertEqual(contact1, r._buckets[0]._contacts[0])
Esempio n. 15
0
 def test_remove_contact_with_unknown_contact(self):
     """
     Ensures that attempting to remove a non-existent contact results in
     no change.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     contact1 = PeerNode(PUBLIC_KEY, self.version,
                         'netstring://192.168.0.1:9999/', 0)
     contact1.network_id = 'a'
     r.add_contact(contact1)
     # Sanity check
     self.assertEqual(len(r._buckets[0]), 1)
     result = r.remove_contact('b')
     self.assertEqual(None, result)
     self.assertEqual(len(r._buckets[0]), 1)
     self.assertEqual(contact1, r._buckets[0]._contacts[0])