def test_kbucket_remove(): bucket = KBucket(0, 100, size=25) nodes = NodeFactory.create_batch(bucket.size) for node in nodes: bucket.add(node) assert bucket.nodes == nodes assert bucket.replacement_cache == [] replacement_count = 10 replacement_nodes = NodeFactory.create_batch(replacement_count) for replacement_node in replacement_nodes: bucket.add(replacement_node) assert bucket.nodes == nodes assert bucket.replacement_cache == replacement_nodes for node in nodes: bucket.remove_node(node) assert bucket.nodes == list(reversed(replacement_nodes)) assert bucket.replacement_cache == [] for replacement_node in replacement_nodes: bucket.remove_node(replacement_node) assert bucket.nodes == [] assert bucket.replacement_cache == []
def test_kbucket_replacement_cache(): # Check that the replacement cache has a limited size and doesn't contain duplicates. # The min/max IDs are irrelevant here as we'll forcibly add nodes to the bucket. bucket = KBucket(0, 10, size=10) for node in NodeFactory.create_batch(bucket.size): bucket.add(node) assert bucket.replacement_cache == [] # Our bucket is now full, so new entries will go to the replacement cache in the order they # were added. assert bucket.is_full overflow_nodes = NodeFactory.create_batch(bucket.size) for node in overflow_nodes: bucket.add(node) assert bucket.replacement_cache == overflow_nodes # If we try to add a node that is already in the replacement cache, it is simply moved to the # tail of the list. bucket.add(overflow_nodes[3]) assert bucket.replacement_cache.index(overflow_nodes[3]) == bucket.size - 1 # Adding a fresh batch of nodes will cause the ones currently in the replacement cache to be # discarded. cache_overflow_nodes = NodeFactory.create_batch(bucket.size) for node in cache_overflow_nodes: bucket.add(node) assert bucket.replacement_cache[-1] == node assert bucket.replacement_cache == cache_overflow_nodes
def test_kbucket_split(): bucket = KBucket(0, 100) for i in range(1, bucket.size + 1): node = NodeFactory() # Set the IDs of half the nodes below the midpoint, so when we split we should end up with # two buckets containing k/2 nodes. if i % 2 == 0: node._id_int = bucket.midpoint + i else: node._id_int = bucket.midpoint - i bucket.add(node) assert bucket.is_full bucket1, bucket2 = bucket.split() assert bucket1.start == 0 assert bucket1.end == 50 assert bucket2.start == 51 assert bucket2.end == 100 assert len(bucket1) == bucket.size / 2 assert len(bucket2) == bucket.size / 2
def test_kbucket_add(): bucket = KBucket(0, 100) node = NodeFactory() assert bucket.add(node) is None assert bucket.nodes == [node] node2 = NodeFactory() assert bucket.add(node2) is None assert bucket.nodes == [node, node2] assert bucket.head == node assert bucket.add(node) is None assert bucket.nodes == [node2, node] assert bucket.head == node2 bucket.size = 2 node3 = NodeFactory() assert bucket.add(node3) == node2 assert bucket.nodes == [node2, node] assert bucket.head == node2