def testHashSpaceRepeatableLookups(self): hashSpace = Flexihash() for i in range(1, 10): hashSpace.addTarget("target" + str(i)) self.assertEqual(hashSpace.lookup('t1'), hashSpace.lookup('t1')) self.assertEqual(hashSpace.lookup('t2'), hashSpace.lookup('t2'))
def testGetMultipleTargetsWithOnlyOneTarget(self): hashSpace = Flexihash() hashSpace.addTarget("single-target") targets = hashSpace.lookupList('resource', 2) self.assertIsInstance(targets, list) self.assertEqual(len(targets), 1) self.assertEqual(targets[0], 'single-target')
def testGetMultipleTargets(self): hashSpace = Flexihash() for i in range(1, 10): hashSpace.addTarget("target" + str(i)) targets = hashSpace.lookupList('resource', 2) self.assertIsInstance(targets, list) self.assertEqual(len(targets), 2) self.assertNotEqual(targets[0], targets[1])
def testGetMoreTargetsThanExist(self): hashSpace = Flexihash() hashSpace.addTarget("target1") hashSpace.addTarget("target2") targets = hashSpace.lookupList('resource', 4) self.assertIsInstance(targets, list) self.assertEqual(len(targets), 2) self.assertNotEqual(targets[0], targets[1])
def test_basic(self): fh = Flexihash() fh.addTarget("a") fh.addTarget("b") fh.addTarget("c") self.assertEqual(fh.lookup("1"), "a") self.assertEqual(fh.lookup("2"), "b") self.assertEqual(fh.lookup("3"), "a")
def testHashSpaceConsistentLookupsWithNewInstance(self): hashSpace1 = Flexihash() for i in range(1, 10): hashSpace1.addTarget("target" + str(i)) results1 = [] for i in range(1, 100): results1.append(hashSpace1.lookup("t" + str(i))) hashSpace2 = Flexihash() for i in range(1, 10): hashSpace2.addTarget("target" + str(i)) results2 = [] for i in range(1, 100): results2.append(hashSpace2.lookup("t" + str(i))) self.assertEqual(results1, results2)
def testHashSpaceConsistentLookupsWithNewInstance(self): hashSpace1 = Flexihash() for i in range(1, 10): hashSpace1.addTarget("target" + str(i)) results1 = [] for i in range(1, 100): results1.append(hashSpace1.lookup("t"+str(i))) hashSpace2 = Flexihash() for i in range(1, 10): hashSpace2.addTarget("target" + str(i)) results2 = [] for i in range(1, 100): results2.append(hashSpace2.lookup("t"+str(i))) self.assertEqual(results1, results2)
def testFallbackPrecedenceWhenServerRemoved(self): mockHasher = MockHasher() hashSpace = Flexihash(mockHasher, 1) mockHasher.setHashValue(10) hashSpace.addTarget("t1") mockHasher.setHashValue(20) hashSpace.addTarget("t2") mockHasher.setHashValue(30) hashSpace.addTarget("t3") mockHasher.setHashValue(15) self.assertEqual(hashSpace.lookup('resource'), 't2') self.assertEqual(hashSpace.lookupList('resource', 3), ['t2', 't3', 't1']) hashSpace.removeTarget('t2') self.assertEqual(hashSpace.lookup('resource'), 't3') self.assertEqual(hashSpace.lookupList('resource', 3), ['t3', 't1']) hashSpace.removeTarget('t3') self.assertEqual(hashSpace.lookup('resource'), 't1') self.assertEqual(hashSpace.lookupList('resource', 3), ['t1'])
def testHashSpaceConsistentLookupsAfterAddingAndRemoving(self): hashSpace = Flexihash() for i in range(1, 10): hashSpace.addTarget("target" + str(i)) results1 = [] for i in range(1, 100): results1.append(hashSpace.lookup("t"+str(i))) hashSpace \ .addTarget('new-target') \ .removeTarget('new-target') \ .addTarget('new-target') \ .removeTarget('new-target') results2 = [] for i in range(1, 100): results2.append(hashSpace.lookup("t"+str(i))) # This is probably optimistic, as adding/removing a target may # clobber existing targets and is not expected to restore them. self.assertEqual(results1, results2)
def testHashSpaceConsistentLookupsAfterAddingAndRemoving(self): hashSpace = Flexihash() for i in range(1, 10): hashSpace.addTarget("target" + str(i)) results1 = [] for i in range(1, 100): results1.append(hashSpace.lookup("t" + str(i))) hashSpace \ .addTarget('new-target') \ .removeTarget('new-target') \ .addTarget('new-target') \ .removeTarget('new-target') results2 = [] for i in range(1, 100): results2.append(hashSpace.lookup("t" + str(i))) # This is probably optimistic, as adding/removing a target may # clobber existing targets and is not expected to restore them. self.assertEqual(results1, results2)
def testGetMultipleTargetsNeedingToLoopToStart(self): mockHasher = MockHasher() hashSpace = Flexihash(mockHasher, 1) mockHasher.setHashValue(10) hashSpace.addTarget("t1") mockHasher.setHashValue(20) hashSpace.addTarget("t2") mockHasher.setHashValue(30) hashSpace.addTarget("t3") mockHasher.setHashValue(40) hashSpace.addTarget("t4") mockHasher.setHashValue(50) hashSpace.addTarget("t5") mockHasher.setHashValue(35) targets = hashSpace.lookupList('resource', 4) self.assertEqual(targets, ['t4', 't5', 't1', 't2'])
def testLookupListReturnsWithShortListIfAllTargetsUsed(self): hashSpace = Flexihash() # both have CRC32 of 1253617450 hashSpace.addTarget("x").addTarget("y") # make the list non-empty, non-one-value, to avoid shortcuts hashSpace.addTarget("80726") # add a value hashSpace.addTarget("14746907") # add a different value with the same hash, to clobber the first hashSpace.removeTarget("14746907") # remove the fourth value; with the third clobbered, only X and Y are left result = hashSpace.lookupList('test', 3) # try to get 3 results, our target list is X, Y, 80726 self.assertEqual(len(result), 2) # but 80726 isn't reachable since it was clobbered self.assertIn("x", result) # all that's left is x self.assertIn("y", result) # and y
def testGetMultipleTargetsWithoutNeedingToLoopToStart(self): mockHasher = MockHasher() hashSpace = Flexihash(mockHasher, 1) mockHasher.setHashValue(10) hashSpace.addTarget("t1") mockHasher.setHashValue(20) hashSpace.addTarget("t2") mockHasher.setHashValue(30) hashSpace.addTarget("t3") mockHasher.setHashValue(15) targets = hashSpace.lookupList('resource', 2) self.assertEqual(targets, ['t2', 't3'])
def testLookupListReturnsWithShortListIfAllTargetsUsed(self): hashSpace = Flexihash() # both have CRC32 of 1253617450 hashSpace.addTarget("x").addTarget( "y") # make the list non-empty, non-one-value, to avoid shortcuts hashSpace.addTarget("80726") # add a value hashSpace.addTarget( "14746907" ) # add a different value with the same hash, to clobber the first hashSpace.removeTarget( "14746907" ) # remove the fourth value; with the third clobbered, only X and Y are left result = hashSpace.lookupList( 'test', 3) # try to get 3 results, our target list is X, Y, 80726 self.assertEqual(len(result), 2) # but 80726 isn't reachable since it was clobbered self.assertIn("x", result) # all that's left is x self.assertIn("y", result) # and y
def testFallbackPrecedenceWhenServerRemoved(self): mockHasher = MockHasher() hashSpace = Flexihash(mockHasher, 1) mockHasher.setHashValue(10) hashSpace.addTarget("t1") mockHasher.setHashValue(20) hashSpace.addTarget("t2") mockHasher.setHashValue(30) hashSpace.addTarget("t3") mockHasher.setHashValue(15) self.assertEqual(hashSpace.lookup('resource'), 't2') self.assertEqual( hashSpace.lookupList('resource', 3), ['t2', 't3', 't1'] ) hashSpace.removeTarget('t2') self.assertEqual(hashSpace.lookup('resource'), 't3') self.assertEqual( hashSpace.lookupList('resource', 3), ['t3', 't1'] ) hashSpace.removeTarget('t3') self.assertEqual(hashSpace.lookup('resource'), 't1') self.assertEqual( hashSpace.lookupList('resource', 3), ['t1'] )
def testAddTargetThrowsExceptionOnDuplicateTarget(self): hashSpace = Flexihash() hashSpace.addTarget('t-a') self.assertRaises(FlexihashException, hashSpace.addTarget, 't-a')
def testAddTargetThrowsExceptionOnDuplicateTarget(self): hashSpace = Flexihash() hashSpace.addTarget('t-a') self.assertRaises(Flexihash_Exception, hashSpace.addTarget, 't-a')