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)
def test_split_bucket_cache_too_full(self): """ If the split occurs and there are too many contacts and cached contacts for a new bucket, the remainder or cached contacts are added to the cache for the new bucket. """ parent_node_id = 'deadbeef' r = RoutingTable(parent_node_id) bucket = Bucket(0, 100) low_contacts = [] high_contacts = [] for i in range(10): contact = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0) contact.network_id = hex(i) bucket.add_contact(contact) low_contacts.append(contact) for i in range(50, 60): contact = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0) contact.network_id = hex(i) bucket.add_contact(contact) high_contacts.append(contact) r._buckets[0] = bucket # Add items to the cache. cache = [] low_cache = [] high_cache = [] for i in range(10, 30): contact = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0) contact.network_id = hex(i) cache.append(contact) low_cache.append(contact) for i in range(60, 80): contact = PeerNode(PUBLIC_KEY, '192.168.0.1', 9999, 0) contact.network_id = hex(i) cache.append(contact) high_cache.append(contact) 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(20, len(bucket1._contacts)) self.assertEqual(20, len(bucket2._contacts)) for i in range(10): self.assertEqual(low_contacts[i], bucket1._contacts[i]) self.assertEqual(low_cache[i], bucket1._contacts[i + 10]) for i in range(10): self.assertEqual(high_contacts[i], bucket2._contacts[i]) self.assertEqual(high_cache[i], bucket2._contacts[i + 10]) # 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) self.assertEqual(10, len(r._replacement_cache[(0, 50)])) self.assertEqual(10, len(r._replacement_cache[(50, 100)])) for i in range(10): self.assertEqual(low_cache[i + 10], r._replacement_cache[(0, 50)][i]) self.assertEqual(high_cache[i + 10], r._replacement_cache[(50, 100)][i])