예제 #1
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 = 'abc'
     r = RoutingTable(parent_node_id)
     # Populate the routing table with contacts.
     for i in range(512):
         contact = PeerNode(2 ** i, "192.168.0.%d" % i, 9999, self.version,
                            0)
         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 = 2 ** 512
         r.find_close_nodes(big_id)
예제 #2
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 = PeerNode(i, "192.168.0.%d" % i, 9999, self.version, 0)
         r.add_contact(contact)
     result = r.find_close_nodes(hex(1))
     self.assertEqual(10, len(result))
예제 #3
0
 def test_find_close_nodes_single_bucket(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 = PeerNode(i, "192.168.0.%d" % i, 9999, self.version, 0)
         r.add_contact(contact)
     result = r.find_close_nodes(hex(1))
     self.assertEqual(constants.K, len(result))
예제 #4
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 = PeerNode(i, "192.168.0.%d" % i, 9999, self.version, 0)
         r.add_contact(contact)
     result = r.find_close_nodes(hex(1), network_id=contact.network_id)
     self.assertEqual(constants.K - 1, len(result))
예제 #5
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 = PeerNode(2 ** i, "192.168.0.%d" % i, 9999, self.version,
                            0)
         r.add_contact(contact)
     result = r.find_close_nodes(long_to_hex(2 ** 256))
     self.assertEqual(constants.K, len(result))
예제 #6
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 = 'abc'
        r = RoutingTable(parent_node_id)
        # Fill up the bucket and replacement cache
        for i in range(512):
            contact = PeerNode(2 ** i, "192.168.0.%d" % i, 9999, self.version,
                               0)
            r.add_contact(contact)
        target_key = long_to_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)