go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/consistenthash/stable_hash_test.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package consistenthash 9 10 import ( 11 "fmt" 12 "math" 13 "testing" 14 15 "go.charczuk.com/sdk/assert" 16 ) 17 18 func Test_StableHash_isStable(t *testing.T) { 19 testCases := [...]struct { 20 Input string 21 Expected uint64 22 }{ 23 {"foo-bar-baz", 0xa9149ad391cbf70}, 24 {"google.com", 0x2bd77c4f0536f5a}, 25 {"worker-5", 0x6e6fa143a67225c3}, 26 {"worker-5|0", 0x73ea7a9251bec4d}, 27 } 28 29 for _, testCase := range testCases { 30 assert.ItsEqual(t, 31 testCase.Expected, 32 StableHash([]byte(testCase.Input)), 33 fmt.Sprintf("%s should be %x", testCase.Input, StableHash([]byte(testCase.Input))), 34 ) 35 } 36 } 37 38 func Test_StableHash_isMostlyUniform(t *testing.T) { 39 const buckets = 5 40 const replicas = 32 41 const maxError = 8 42 43 values := make(map[uint64]int) 44 for bucket := 0; bucket < buckets; bucket++ { 45 for replica := 0; replica < replicas; replica++ { 46 hashValue := StableHash([]byte(fmt.Sprintf("worker-%d|%d", bucket, replica))) 47 hashedBucket := hashValue % buckets 48 values[hashedBucket]++ 49 } 50 } 51 var min, max int = math.MaxInt32, math.MinInt32 52 for _, value := range values { 53 if value > max { 54 max = value 55 } 56 if value < min { 57 min = value 58 } 59 } 60 assert.ItsEqual(t, true, max-min <= maxError, fmt.Sprintf("expect the count delta between %d and %d to be %d", max, min, maxError)) 61 }