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  }