def test_remove_existing_node(self):
        ring = hashring.ConsistentHashRing({'a': None, 'b': None})
        self.assertEqual(2, len(ring))
        self.assertEqual(80, len(ring._ring))
        ring.remove_nodes(['c', 'a'])
        self.assertEqual(1, len(ring))
        self.assertEqual(40, len(ring._ring))

        ring = hashring.ConsistentHashRing({'a': 3, 'b': 2})
        self.assertEqual(2, len(ring))
        self.assertEqual(200, len(ring._ring))
        ring.remove_nodes(['b', 'c'])
        self.assertEqual(1, len(ring))
        self.assertEqual(120, len(ring._ring))
    def test_consistency(self):
        # Create many rings with all the same cluster, and verify that
        # they get the same result for different keys
        cluster = dict([(str(x), None) for x in range(100)])

        # 10 rings
        rings = [hashring.ConsistentHashRing(cluster, replicas=2)
                 for x in range(10)]
        # They are all different instances with the same configuration,
        # keys must be assigned in the same way
        # Hash 100 keys
        for x in range(100):
            key = str(uuid.uuid4())
            result = set(tuple(y.assign_key(key)) for y in rings)
            self.assertEqual(1, len(result))
            self.assertEqual(2, len(result.pop()))

        # Remove one key from all the rings and the result is the same
        for ring in rings:
            ring.remove_node('9')

        # Still consistently hashed
        for x in range(100):
            key = str(uuid.uuid4())
            result = set(tuple(y.assign_key(key)) for y in rings)
            self.assertEqual(1, len(result))
            self.assertEqual(2, len(result.pop()))
    def test_proportional_weight(self):
        ring = hashring.ConsistentHashRing({'a': None, 'b': None, 'c': None})
        a_count = self._count_replicas(ring, 'a')
        b_count = self._count_replicas(ring, 'b')
        c_count = self._count_replicas(ring, 'c')
        self.assertEqual(a_count, b_count)
        self.assertEqual(a_count, c_count)
        self.assertEqual(a_count, 40)

        ring = hashring.ConsistentHashRing({'a': 1, 'b': 2, 'c': 3})
        a_count = self._count_replicas(ring, 'a')
        b_count = self._count_replicas(ring, 'b')
        c_count = self._count_replicas(ring, 'c')
        self.assertEqual(a_count * 2, b_count)
        self.assertEqual(a_count * 3, c_count)
        self.assertEqual(a_count, 40)
    def test_update_weight(self):
        ring = hashring.ConsistentHashRing({'a': 1, 'b': 2, 'c': 3})
        a_count = self._count_replicas(ring, 'a')

        ring.add_node('a', 6)
        a_count2 = self._count_replicas(ring, 'a')
        self.assertEqual(6, a_count2 / a_count)
    def test_remove_non_existing_node(self):
        ring = hashring.ConsistentHashRing({'a': None, 'b': None})
        self.assertEqual(2, len(ring))
        self.assertEqual(80, len(ring._ring))
        ring.remove_node('c')
        # Nothing happened
        self.assertEqual(2, len(ring))
        self.assertEqual(80, len(ring._ring))

        ring = hashring.ConsistentHashRing({'a': 3, 'b': 2})
        self.assertEqual(2, len(ring))
        self.assertEqual(200, len(ring._ring))
        ring.remove_node('c')
        # Nothing happened
        self.assertEqual(2, len(ring))
        self.assertEqual(200, len(ring._ring))
 def test_distribution(self):
     results = set()
     ring = hashring.ConsistentHashRing({'a': None, 'b': None, 'c': None})
     for x in range(15):
         key = str(uuid.uuid4())
         result = ring.assign_key(key)
         results.add(result[0])
     self.assertEqual(results, set(['a', 'b', 'c']))
    def test_replicas(self):
        # One one, only one replica regardless
        ring = hashring.ConsistentHashRing({'a': None})
        allocation = ring.assign_key('somekey')
        self.assertEqual(allocation, ['a'])

        # Add a node and recheck the allocation
        ring.add_node('b', None)
        allocation = ring.assign_key('somekey')
        self.assertEqual(set(allocation), set(['a', 'b']))

        # Add another node, result is always 2
        ring.add_node('c', None)
        allocation = ring.assign_key('somekey')
        self.assertEqual(2, len(allocation))
Beispiel #8
0
 def _tenant_assignation_algorithm(self, aim_ctx, agents):
     # TODO(ivar): just randomly hash each tenant to agents for now. This
     # algorithm should be made way more optimal (through the use of
     # consistent hashing) and possibly pluggable.
     result = []
     try:
         agents.index(self.agent)
     except ValueError:
         # This agent is down
         return result
     # TODO(ivar): In future, for better resource usage, each agent
     # could have a weight value in the DB definition
     ring = hashring.ConsistentHashRing(dict([(x.id, None)
                                              for x in agents]))
     # retrieve tenants
     for tenant in self.tree_manager.get_roots(aim_ctx):
         allocations = ring.assign_key(tenant)
         if self.agent_id in allocations:
             result.append(tenant)
     return result
 def test_init(self):
     ring = hashring.ConsistentHashRing(
         dict((str(x), None) for x in range(10)))
     self.assertEqual(10, len(ring))
     self.assertEqual(400, len(ring._ring))
 def test_remove_non_existing_node(self):
     ring = hashring.ConsistentHashRing({'a': None})
     ring.remove_node('b')
     # Nothing happened
     self.assertEqual(1, len(ring))