def test_closest_nodes_only_additional(empty_routing_table): target = NodeIDFactory() nodes = [NodeIDFactory() for _ in range(10)] closest_nodes = list(iter_closest_nodes(target, empty_routing_table, nodes)) assert closest_nodes == sorted( nodes, key=lambda node: compute_distance(target, node))
def test_closest_nodes_only_routing(empty_routing_table): target = NodeIDFactory() nodes = [NodeIDFactory() for _ in range(10)] for node in nodes: empty_routing_table.update(node) closest_nodes = list(iter_closest_nodes(target, empty_routing_table, [])) assert closest_nodes == sorted(nodes, key=lambda node: compute_distance(target, node))
def test_get_nodes_at_log_distance(routing_table, center_node_id, bucket_size): nodes = tuple(NodeIDFactory.at_log_distance(center_node_id, 200) for _ in range(bucket_size)) farther_nodes = tuple(NodeIDFactory.at_log_distance(center_node_id, 201) for _ in range(5)) closer_nodes = tuple(NodeIDFactory.at_log_distance(center_node_id, 199) for _ in range(5)) for node_id in nodes + farther_nodes + closer_nodes: routing_table.update(node_id) assert set(routing_table.get_nodes_at_log_distance(200)) == set(nodes)
def test_update(routing_table, center_node_id): node_id_1 = NodeIDFactory.at_log_distance(center_node_id, 200) node_id_2 = NodeIDFactory.at_log_distance(center_node_id, 200) routing_table.update(node_id_1) routing_table.update(node_id_2) assert routing_table.get_nodes_at_log_distance(200) == (node_id_2, node_id_1) routing_table.update(node_id_2) assert routing_table.get_nodes_at_log_distance(200) == (node_id_2, node_id_1) routing_table.update(node_id_1) assert routing_table.get_nodes_at_log_distance(200) == (node_id_1, node_id_2)
def test_lookup_generator_mixed(empty_routing_table): target = NodeIDFactory() nodes = sorted([NodeIDFactory() for _ in range(10)], key=lambda node: compute_distance(node, target)) nodes_in_routing_table = nodes[:3] + nodes[6:8] nodes_in_additional = nodes[3:6] + nodes[8:] for node in nodes_in_routing_table: empty_routing_table.update(node) closest_nodes = list( iter_closest_nodes(target, empty_routing_table, nodes_in_additional)) assert closest_nodes == nodes
def test_add_or_update(routing_table): first_node_id = NodeIDFactory() second_node_id = NodeIDFactory() routing_table.add_or_update(first_node_id) assert first_node_id in routing_table routing_table.add(second_node_id) assert routing_table.get_oldest_entry() == first_node_id routing_table.add_or_update(first_node_id) assert routing_table.get_oldest_entry() == second_node_id
def test_update(routing_table): first_node_id = NodeIDFactory() second_node_id = NodeIDFactory() with pytest.raises(KeyError): routing_table.update(first_node_id) routing_table.add(first_node_id) routing_table.add(second_node_id) assert routing_table.get_oldest_entry() == first_node_id routing_table.update(first_node_id) assert routing_table.get_oldest_entry() == second_node_id
def test_iter_around(routing_table, center_node_id): reference_node_id = NodeIDFactory.at_log_distance(center_node_id, 100) node_ids = tuple( NodeIDFactory.at_log_distance(reference_node_id, distance) for distance in (1, 2, 100, 200) ) for node_id in node_ids: routing_table.update(node_id) assert tuple(routing_table.iter_nodes_around(reference_node_id)) == node_ids assert tuple(routing_table.iter_nodes_around(node_ids[0])) == node_ids assert tuple(routing_table.iter_nodes_around(node_ids[-1])) != node_ids
def test_add(routing_table): node_id = NodeIDFactory() assert node_id not in routing_table routing_table.add(node_id) assert node_id in routing_table with pytest.raises(ValueError): routing_table.add(node_id)
def test_iter_all_random(routing_table, center_node_id): nodes_in_insertion_order = [] # Use a relatively high number of nodes here otherwise we could have two consecutive calls # yielding nodes in the same order. for _ in range(100): node_id = NodeIDFactory() routing_table.update(node_id) nodes_in_insertion_order.append(node_id) nodes_in_iteration_order = [ node for node in routing_table.iter_all_random() ] # We iterate over all nodes table_length = sum( len(l) for l in itertools.chain(routing_table.buckets, routing_table.replacement_caches)) assert len(nodes_in_iteration_order) == table_length == len( nodes_in_insertion_order) # No repeated nodes are returned assert len(set(nodes_in_iteration_order)) == len(nodes_in_iteration_order) # The order in which we iterate is not the same as the one in which nodes were inserted. assert nodes_in_iteration_order != nodes_in_insertion_order second_iteration_order = [node for node in routing_table.iter_all_random()] # Multiple calls should yield the same nodes, but in a different order. assert set(nodes_in_iteration_order) == set(second_iteration_order) assert nodes_in_iteration_order != second_iteration_order
def test_is_empty(routing_table): assert routing_table.is_empty node_id = NodeIDFactory() routing_table.update(node_id) assert not routing_table.is_empty routing_table.remove(node_id) assert routing_table.is_empty
def test_remove(routing_table): node_id = NodeIDFactory() with pytest.raises(KeyError): routing_table.remove(node_id) routing_table.add(node_id) routing_table.remove(node_id) assert node_id not in routing_table
def test_add(routing_table, center_node_id): assert routing_table.get_nodes_at_log_distance(255) == () node_id_1 = NodeIDFactory.at_log_distance(center_node_id, 255) routing_table.update(node_id_1) assert routing_table.get_nodes_at_log_distance(255) == (node_id_1,) node_id_2 = NodeIDFactory.at_log_distance(center_node_id, 255) routing_table.update(node_id_2) assert routing_table.get_nodes_at_log_distance(255) == (node_id_2, node_id_1) node_id_3 = NodeIDFactory.at_log_distance(center_node_id, 255) routing_table.update(node_id_3) assert routing_table.get_nodes_at_log_distance(255) == (node_id_2, node_id_1) node_id_4 = NodeIDFactory.at_log_distance(center_node_id, 1) routing_table.update(node_id_4) assert routing_table.get_nodes_at_log_distance(1) == (node_id_4,)
def test_remove(routing_table, center_node_id): node_id_1 = NodeIDFactory.at_log_distance(center_node_id, 200) node_id_2 = NodeIDFactory.at_log_distance(center_node_id, 200) node_id_3 = NodeIDFactory.at_log_distance(center_node_id, 200) node_id_4 = NodeIDFactory.at_log_distance(center_node_id, 200) routing_table.update(node_id_1) routing_table.update(node_id_2) routing_table.update(node_id_3) routing_table.update(node_id_4) assert routing_table.get_nodes_at_log_distance(200) == (node_id_2, node_id_1) routing_table.remove(node_id_4) # remove from replacement cache, shouldn't appear again routing_table.remove(node_id_2) assert routing_table.get_nodes_at_log_distance(200) == (node_id_1, node_id_3) routing_table.remove(node_id_3) assert routing_table.get_nodes_at_log_distance(200) == (node_id_1,) routing_table.remove(node_id_1) assert routing_table.get_nodes_at_log_distance(200) == () routing_table.remove(node_id_1) # shouldn't raise
def test_least_recently_updated_distance(routing_table, center_node_id): with pytest.raises(ValueError): routing_table.get_least_recently_updated_log_distance() node_id_1 = NodeIDFactory.at_log_distance(center_node_id, 200) routing_table.update(node_id_1) assert routing_table.get_least_recently_updated_log_distance() == 200 node_id_2 = NodeIDFactory.at_log_distance(center_node_id, 100) routing_table.update(node_id_2) assert routing_table.get_least_recently_updated_log_distance() == 200 routing_table.update(node_id_1) assert routing_table.get_least_recently_updated_log_distance() == 100 routing_table.remove(node_id_1) assert routing_table.get_least_recently_updated_log_distance() == 100 routing_table.remove(node_id_2) with pytest.raises(ValueError): routing_table.get_least_recently_updated_log_distance()
async def test_ping_handler_updates_routing_table(ping_handler, incoming_message_channels, outgoing_message_channels, local_enr, remote_enr, routing_table): other_node_id = NodeIDFactory() routing_table.add(other_node_id) assert routing_table.get_oldest_entry() == remote_enr.node_id ping = PingMessageFactory() incoming_message = IncomingMessageFactory( message=ping, sender_node_id=remote_enr.node_id, ) await incoming_message_channels[0].send(incoming_message) await wait_all_tasks_blocked() assert routing_table.get_oldest_entry() == other_node_id
async def test_ping_handler_updates_routing_table(ping_handler_service, incoming_message_channels, outgoing_message_channels, local_enr, remote_enr, routing_table): distance = compute_log_distance(remote_enr.node_id, local_enr.node_id) other_node_id = NodeIDFactory.at_log_distance(local_enr.node_id, distance) routing_table.update(other_node_id) assert routing_table.get_nodes_at_log_distance(distance) == (other_node_id, remote_enr.node_id) ping = PingMessageFactory() incoming_message = IncomingMessageFactory( message=ping, sender_node_id=remote_enr.node_id, ) await incoming_message_channels[0].send(incoming_message) await wait_all_tasks_blocked() assert routing_table.get_nodes_at_log_distance(distance) == (remote_enr.node_id, other_node_id)
def test_closest_nodes_empty(empty_routing_table): target = NodeIDFactory() assert list(iter_closest_nodes(target, empty_routing_table, [])) == []
def test_fill_bucket(routing_table, center_node_id, bucket_size): assert not routing_table.get_nodes_at_log_distance(200) for _ in range(2 * bucket_size): routing_table.update(NodeIDFactory.at_log_distance(center_node_id, 200)) assert len(routing_table.get_nodes_at_log_distance(200)) == bucket_size
def center_node_id(): return NodeIDFactory()