Ejemplo n.º 1
0
 def test_restore_with_contacts_and_blacklist(self):
     """
     Ensures that any contacts also in the blacklist are actually
     blacklisted and removed from the routing table.
     """
     blacklist = [BAD_PUBLIC_KEY, ]
     contacts = []
     uri = 'netstring://192.168.0.1:9999/'
     contacts.append({
         'public_key': PUBLIC_KEY,
         'version': self.version,
         'uri': uri,
     })
     contacts.append({
         'public_key': BAD_PUBLIC_KEY,
         'version': self.version,
         'uri': uri,
     })
     data_dump = {
         'contacts': contacts,
         'blacklist': blacklist,
     }
     parent_node_id = 'deadbeef'
     rt = RoutingTable(parent_node_id)
     rt.restore(data_dump)
     self.assertEqual(len(rt._buckets[0]), 1)
     self.assertEqual(len(rt._blacklist), 1)
Ejemplo n.º 2
0
    def test_find_close_nodes_in_correct_order(self):
        """
        Ensures that the nearest nodes are returned in the correct order: from
        the node closest to the target key to the node furthest away.
        """
        parent_node_id = 'deadbeef'
        r = RoutingTable(parent_node_id)
        # Fill up the bucket and replacement cache
        for i in range(512):
            uri = 'netstring://192.168.0.%d:9999/' % i
            contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
            contact.network_id = hex(2 ** i)
            r.add_contact(contact)
        target_key = hex(2 ** 256)
        result = r.find_close_nodes(target_key)
        self.assertEqual(constants.K, len(result))

        # Ensure results are in the correct order.
        def key(node):
            return distance(node.network_id, target_key)
        sorted_nodes = sorted(result, key=key)
        self.assertEqual(sorted_nodes, result)
        # Ensure the order is from lowest to highest in terms of distance
        distances = [distance(x.network_id, target_key) for x in result]
        self.assertEqual(sorted(distances), distances)
Ejemplo n.º 3
0
 def test_dump(self):
     """
     Ensures that the expected dictionary is returned from a call to the
     dump method (used to back up the routing table).
     """
     contacts = []
     blacklist = [BAD_PUBLIC_KEY, ]
     uri = 'netstring://192.168.0.1:9999/'
     contacts.append({
         'public_key': PUBLIC_KEY,
         'version': self.version,
         'uri': uri,
     })
     data_dump = {
         'contacts': contacts,
         'blacklist': blacklist,
     }
     parent_node_id = 'deadbeef'
     rt = RoutingTable(parent_node_id)
     rt.restore(data_dump)
     result = rt.dump()
     self.assertIn('blacklist', result)
     self.assertIn('contacts', result)
     self.assertEqual(1, len(result['blacklist']))
     self.assertIn(BAD_PUBLIC_KEY, result['blacklist'])
     self.assertEqual(1, len(result['contacts']))
     self.assertEqual(PUBLIC_KEY, result['contacts'][0]['public_key'])
     self.assertEqual(self.version, result['contacts'][0]['version'])
     self.assertEqual(uri, result['contacts'][0]['uri'])
     # check it can be serialised into JSON
     dump = json.dumps(result)
     self.assertIsInstance(dump, str)
Ejemplo n.º 4
0
 def test_get_contact_does_not_exist(self):
     """
     Ensures that a ValueError is returned if the referenced contact does
     not exist in the routing table.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
     r.add_contact(contact1)
     self.assertRaises(ValueError, r.get_contact, 'b')
Ejemplo n.º 5
0
 def test_get_contact(self):
     """
     Ensures that the correct contact is returned.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     contact1 = Contact('a', '192.168.0.1', 9999, self.version, 0)
     r.add_contact(contact1)
     result = r.get_contact('a')
     self.assertEqual(contact1, result)
Ejemplo n.º 6
0
 def test_add_contact_with_parent_node_id(self):
     """
     If the newly discovered contact is, in fact, this node then it's not
     added to the routing table.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     contact = Contact('abc', '192.168.0.1', 9999, 0)
     r.add_contact(contact)
     self.assertEqual(len(r._buckets[0]), 0)
Ejemplo n.º 7
0
 def test_random_key_in_bucket_range(self):
     """
     Ensures the returned key is within the expected bucket range.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     bucket = Bucket(1, 2)
     r._buckets[0] = bucket
     expected = 1
     actual = int(r._random_key_in_bucket_range(0), 0)
     self.assertEqual(expected, actual)
Ejemplo n.º 8
0
 def test_add_contact_with_parent_node_id(self):
     """
     If the newly discovered contact is, in fact, this node then it's not
     added to the routing table.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     contact = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0)
     contact.network_id = parent_node_id
     r.add_contact(contact)
     self.assertEqual(len(r._buckets[0]), 0)
Ejemplo n.º 9
0
 def test_distance(self):
     """
     Sanity check to ensure the XOR'd values return the correct distance.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     key1 = 'abc'
     key2 = 'xyz'
     expected = 1645337L
     actual = r.distance(key1, key2)
     self.assertEqual(expected, actual)
Ejemplo n.º 10
0
 def test_get_contact_does_not_exist(self):
     """
     Ensures that a ValueError is returned if the referenced contact does
     not exist in 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)
     r.add_contact(contact1)
     self.assertRaises(ValueError, r.get_contact, 'b')
Ejemplo n.º 11
0
 def test_find_close_nodes_fewer_than_K(self):
     """
     Ensures that all close nodes are returned if their number is < K.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(10):
         contact = Contact(i, "192.168.0.%d" % i, self.version, 0)
         r.add_contact(contact)
     result = r.find_close_nodes(1)
     self.assertEqual(10, len(result))
Ejemplo n.º 12
0
 def test_find_close_nodes_single_kbucket(self):
     """
     Ensures K number of closest nodes get returned.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(40):
         contact = Contact(i, "192.168.0.%d" % i, self.version, 0)
         r.add_contact(contact)
     result = r.find_close_nodes(1)
     self.assertEqual(20, len(result))
Ejemplo n.º 13
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)
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
 def test_bucket_index_single_bucket(self):
     """
     Ensures the expected index is returned when only a single bucket
     exists.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # a simple test with only one bucket in the routing table.
     test_key = 'abc123'
     expected_index = 0
     actual_index = r._bucket_index(test_key)
     self.assertEqual(expected_index, actual_index)
Ejemplo n.º 16
0
 def test_get_contact(self):
     """
     Ensures that the correct contact is returned.
     """
     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)
     result = r.get_contact('a')
     self.assertEqual(contact1, result)
Ejemplo n.º 17
0
 def test_find_close_nodes_multiple_buckets(self):
     """
     Ensures that nodes are returned from neighbouring k-buckets if the
     k-bucket containing the referenced ID doesn't contain K entries.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(512):
         contact = Contact(2 ** i, "192.168.0.%d" % i, self.version, 0)
         r.add_contact(contact)
     result = r.find_close_nodes(2 ** 256)
     self.assertEqual(20, len(result))
Ejemplo n.º 18
0
 def test_add_contact_simple(self):
     """
     Ensures that a newly discovered node in the network is added to the
     correct kbucket in the routing table.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     contact1 = Contact(2, '192.168.0.1', 9999, 0)
     contact2 = Contact(4, '192.168.0.2', 9999, 0)
     r.add_contact(contact1)
     self.assertEqual(len(r._buckets[0]), 1)
     r.add_contact(contact2)
     self.assertEqual(len(r._buckets[0]), 2)
Ejemplo n.º 19
0
 def test_find_close_nodes_exclude_contact(self):
     """
     Ensure that nearest nodes are returned except for the specified
     excluded node.
     """
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(20):
         contact = Contact(str(i), "192.168.0.%d" % i, self.version, 0)
         r.add_contact(contact)
     result = r.find_close_nodes("1", rpc_node_id=contact)
     self.assertEqual(19, len(result))
Ejemplo n.º 20
0
 def test_random_key_in_bucket_range_long(self):
     """
     Ensures that random_key_in_bucket_range works with large numbers.
     """
     minimum = 978675645342314253647586978
     maximum = 978675645342314253647586979
     parent_node_id = 'abc'
     r = RoutingTable(parent_node_id)
     bucket = KBucket(minimum, maximum)
     r._buckets[0] = bucket
     expected = minimum
     actual = int(r._random_key_in_bucket_range(0).encode('hex'), 16)
     self.assertEqual(expected, actual)
Ejemplo n.º 21
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)
Ejemplo n.º 22
0
 def test_find_close_nodes_fewer_than_K(self):
     """
     Ensures that all close nodes are returned if their number is < K.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(10):
         uri = 'netstring://192.168.0.%d:9999/' % i
         contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
         contact.network_id = hex(i)
         r.add_contact(contact)
     result = r.find_close_nodes(hex(1))
     self.assertEqual(10, len(result))
Ejemplo n.º 23
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)
Ejemplo n.º 24
0
 def test_restore_with_blacklist(self):
     """
     Ensures that a list of network_ids of blacklisted peers can be restored
     into the newly created object.
     """
     data_dump = {
         'blacklist': [PUBLIC_KEY, ],
     }
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     self.assertEqual(len(r._blacklist), 0)
     r.restore(data_dump)
     self.assertEqual(len(r._blacklist), 1)
     self.assertIn(PUBLIC_KEY, r._blacklist)
Ejemplo n.º 25
0
 def test_touch_bucket(self):
     """
     Ensures that the last_accessed field of the affected k-bucket isi
     updated appropriately.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # At this point the single k-bucket in the routing table will have a
     # lastAccessed time of 0 (zero). Sanity check.
     self.assertEqual(0, r._buckets[0].last_accessed)
     # Since all keys are in the range of the single k-bucket any key will
     # do for the purposes of testing.
     r.touch_bucket('abc')
     self.assertNotEqual(0, r._buckets[0].last_accessed)
Ejemplo n.º 26
0
 def test_find_close_nodes_single_bucket(self):
     """
     Ensures K number of closest nodes get returned.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(40):
         uri = 'netstring://192.168.0.%d:9999/' % i
         contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
         contact.network_id = hex(i)
         r.add_contact(contact)
     result = r.find_close_nodes(hex(1))
     self.assertEqual(constants.K, len(result))
Ejemplo n.º 27
0
 def test_find_close_nodes_multiple_buckets(self):
     """
     Ensures that nodes are returned from neighbouring k-buckets if the
     k-bucket containing the referenced ID doesn't contain K entries.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(512):
         uri = 'netstring://192.168.0.%d:9999/' % i
         contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
         contact.network_id = hex(2 ** i)
         r.add_contact(contact)
     result = r.find_close_nodes(hex(2 ** 256))
     self.assertEqual(constants.K, len(result))
Ejemplo n.º 28
0
 def test_find_close_nodes_exclude_contact(self):
     """
     Ensure that nearest nodes are returned except for the specified
     excluded node.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(20):
         uri = 'netstring://192.168.0.%d:9999/' % i
         contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
         contact.network_id = hex(i)
         r.add_contact(contact)
     result = r.find_close_nodes(hex(1), excluded_id=contact.network_id)
     self.assertEqual(constants.K - 1, len(result))
Ejemplo n.º 29
0
 def test_bucket_index_as_string_and_int(self):
     """
     Ensures that the specified key can be expressed as both a string
     and integer value.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # key as a string
     test_key = 'abc123'
     expected_index = 0
     actual_index = r._bucket_index(test_key)
     self.assertEqual(expected_index, actual_index)
     # key as an integer
     test_key = '1234567'
     actual_index = r._bucket_index(test_key)
     self.assertEqual(expected_index, actual_index)
Ejemplo n.º 30
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])
Ejemplo n.º 31
0
 def test_get_refresh_list(self):
     """
     Ensures that only keys from stale k-buckets are returned.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     bucket1 = Bucket(1, 2)
     # Set the lastAccessed flag on bucket 1 to be out of date
     bucket1.last_accessed = time.time() - 3700
     r._buckets[0] = bucket1
     bucket2 = Bucket(2, 3)
     bucket2.last_accessed = time.time()
     r._buckets.append(bucket2)
     expected = 1
     result = r.get_refresh_list(0)
     self.assertEqual(1, len(result))
     self.assertEqual(expected, int(result[0], 0))
Ejemplo n.º 32
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)
Ejemplo n.º 33
0
 def test_init_no_shortlist(self):
     """
     Ensure the Future is marked as done with a RoutingTableEmpty exception.
     """
     # Create an empty routing table.
     self.node.routing_table = RoutingTable(self.node.network_id)
     lookup = Lookup(FindNode, self.target, self.node, self.event_loop)
     self.assertEqual(True, lookup.done())
     self.assertRaises(RoutingTableEmpty, lookup.result)
Ejemplo n.º 34
0
 def test_init(self):
     """
     Ensures an object is created as expected.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # Ensure the initial bucket is created.
     self.assertEqual(1, len(r._buckets))
     # Ensure the parent's node ID is stored.
     self.assertEqual(parent_node_id, r._parent_node_id)
Ejemplo n.º 35
0
 def test_get_forced_refresh_list(self):
     """
     Ensures that keys from all k-buckets (no matter if they're stale or
     not) are returned.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     bucket1 = Bucket(1, 2)
     # Set the lastAccessed flag on bucket 1 to be out of date
     bucket1.last_accessed = time.time() - 3700
     r._buckets[0] = bucket1
     bucket2 = Bucket(2, 3)
     bucket2.last_accessed = time.time()
     r._buckets.append(bucket2)
     result = r.get_refresh_list(0, True)
     # Even though bucket 2 is not stale it still has a key for it in
     # the result.
     self.assertEqual(2, len(result))
     self.assertEqual(1, int(result[0], 0))
     self.assertEqual(2, int(result[1], 0))
Ejemplo n.º 36
0
 def test_restore_with_contacts(self):
     """
     Ensures the routing table can be restored with a list of contacts.
     """
     contacts = []
     uri = 'netstring://192.168.0.1:9999/'
     contacts.append({
         'public_key': PUBLIC_KEY,
         'version': self.version,
         'uri': uri,
     })
     data_dump = {
         'contacts': contacts,
     }
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     self.assertEqual(len(r._buckets[0]), 0)
     r.restore(data_dump)
     self.assertEqual(len(r._buckets[0]), 1)
     self.assertEqual(PUBLIC_KEY, r._buckets[0]._contacts[0].public_key)
Ejemplo n.º 37
0
 def test_add_contact_with_full_replacement_cache(self):
     """
     Ensures that if the replacement cache is full (length = k) then the
     oldest contact within the cache is replaced with the new contact that
     was just seen.
     """
     parent_node_id = hex((2 ** 512) + 1)[2:]
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(40):
         uri = 'netstring://192.168.0.%d:9999/' % i
         contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
         contact.network_id = hex(i)
         r.add_contact(contact)
     # Sanity check of the replacement cache.
     cache_key = (r._buckets[0].range_min, r._buckets[0].range_max)
     self.assertEqual(len(r._replacement_cache[cache_key]), 20)
     self.assertEqual(hex(20),
                      r._replacement_cache[cache_key][0].network_id)
     # Create a new contact that will be added to the replacement cache.
     new_contact = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.20:9999/', 0)
     new_contact.network_id = hex(40)
     r.add_contact(new_contact)
     self.assertEqual(len(r._replacement_cache[cache_key]), 20)
     self.assertEqual(new_contact, r._replacement_cache[cache_key][19])
     self.assertEqual(hex(21),
                      r._replacement_cache[cache_key][0].network_id)
Ejemplo n.º 38
0
 def test_add_contact_with_existing_contact_in_replacement_cache(self):
     """
     Ensures that if the contact to be put in the replacement cache already
     exists in the replacement cache then it is bumped to the most recent
     position.
     """
     parent_node_id = hex((2 ** 512) + 1)[2:]
     r = RoutingTable(parent_node_id)
     # Fill up the bucket and replacement cache
     for i in range(40):
         uri = 'netstring://192.168.0.%d:9999/' % i
         contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
         contact.network_id = hex(i)
         r.add_contact(contact)
     # Sanity check of the replacement cache.
     cache_key = (r._buckets[0].range_min, r._buckets[0].range_max)
     self.assertEqual(len(r._replacement_cache[cache_key]), 20)
     self.assertEqual(hex(20),
                      r._replacement_cache[cache_key][0].network_id)
     # Create a new contact that will be added to the replacement cache.
     new_contact = PeerNode(PUBLIC_KEY, self.version,
                            'netstring://192.168.0.41:9999/', 0)
     new_contact.network_id = hex(20)
     r.add_contact(new_contact)
     self.assertEqual(len(r._replacement_cache[cache_key]), 20)
     self.assertEqual(new_contact, r._replacement_cache[cache_key][19])
     self.assertEqual(hex(21),
                      r._replacement_cache[cache_key][0].network_id)
Ejemplo n.º 39
0
 def test_add_contact_with_blacklisted_contact(self):
     """
     If the newly discovered contact is, in fact, already in the local
     node's blacklist then ensure it doesn't get re-added.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     contact1 = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0)
     contact1.network_id = hex(2)
     contact2 = PeerNode(BAD_PUBLIC_KEY, '192.168.0.2', 9999, 0)
     contact2.network_id = hex(4)
     r.blacklist(contact2)
     r.add_contact(contact1)
     self.assertEqual(len(r._buckets[0]), 1)
     r.add_contact(contact2)
     self.assertEqual(len(r._buckets[0]), 1)
Ejemplo n.º 40
0
 def test_split_bucket_cache_update(self):
     """
     Ensures that if there are cached contacts for the split bucket then
     the two new buckets are topped up, the old cache is removed and two
     new caches created (one for each of the new buckets).
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     bucket = Bucket(0, 100)
     contact1 = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0)
     contact1.network_id = hex(20)
     bucket.add_contact(contact1)
     contact2 = PeerNode(PUBLIC_KEY, '192.168.0.2', 8888, 0)
     contact2.network_id = hex(40)
     bucket.add_contact(contact2)
     contact3 = PeerNode(PUBLIC_KEY, '192.168.0.3', 8888, 0)
     contact3.network_id = hex(60)
     bucket.add_contact(contact3)
     contact4 = PeerNode(PUBLIC_KEY, '192.168.0.4', 8888, 0)
     contact4.network_id = hex(80)
     bucket.add_contact(contact4)
     r._buckets[0] = bucket
     # Add two items to the cache.
     cache = []
     cache_contact1 = PeerNode(PUBLIC_KEY, '192.168.0.5', 8888, 0)
     cache_contact1.network_id = hex(10)
     cache.append(cache_contact1)
     cache_contact2 = PeerNode(PUBLIC_KEY, '192.168.0.6', 8888, 0)
     cache_contact2.network_id = hex(70)
     cache.append(cache_contact2)
     r._replacement_cache = {
         (0, 100): cache
     }
     # Two buckets!
     r._split_bucket(0)
     self.assertEqual(2, len(r._buckets))
     bucket1 = r._buckets[0]
     bucket2 = r._buckets[1]
     # Ensure the right number of contacts are in each bucket in the correct
     # order (most recently added at the head of the list).
     self.assertEqual(3, len(bucket1._contacts))
     self.assertEqual(3, len(bucket2._contacts))
     self.assertEqual(contact1, bucket1._contacts[0])
     self.assertEqual(contact2, bucket1._contacts[1])
     self.assertEqual(cache_contact1, bucket1._contacts[2])
     self.assertEqual(contact3, bucket2._contacts[0])
     self.assertEqual(contact4, bucket2._contacts[1])
     self.assertEqual(cache_contact2, bucket2._contacts[2])
     # Ensure the _replacement_cache is in the expected state.
     self.assertEqual(2, len(r._replacement_cache))
     self.assertNotIn((0, 100), r._replacement_cache)
     self.assertIn((0, 50), r._replacement_cache)
     self.assertIn((50, 100), r._replacement_cache)
Ejemplo n.º 41
0
 def test_bucket_index_out_of_range(self):
     """
     If the requested id is not within the range of the keyspace then a
     ValueError should be raised.
     """
     parent_node_id = 'deadbeef'
     r = RoutingTable(parent_node_id)
     # Populate the routing table with contacts.
     for i in range(512):
         uri = 'netstring://192.168.0.%d:9999/' % i
         contact = PeerNode(PUBLIC_KEY, self.version, uri, 0)
         contact.network_id = hex(2 ** i)
         r.add_contact(contact)
     with self.assertRaises(ValueError):
         # Incoming id that's too small.
         r.find_close_nodes('-1')
     with self.assertRaises(ValueError):
         # Incoming id that's too big
         big_id = hex(2 ** 512)[2:]
         r.find_close_nodes(big_id)
Ejemplo n.º 42
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])