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)
def test_kbucket_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 = Contact(2 ** i, "192.168.0.%d" % i, 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)
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)
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))
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))
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))
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))
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))
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))
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))
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))
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 = Contact(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.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.id, target_key) for x in result] self.assertEqual(sorted(distances), distances)