-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhashring_test.go
107 lines (85 loc) · 2.73 KB
/
hashring_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package hashring
import (
"fmt"
"slices"
"testing"
)
func TestNewHashRing(t *testing.T) {
nodes := []string{"node1", "node2", "node3"}
replicas := 3
hr := New(nodes, replicas)
if len(hr.NodeAddrs) != len(nodes) {
t.Errorf("Expected %d nodes, got %d", len(nodes), len(hr.NodeAddrs))
}
if hr.Replicas != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, hr.Replicas)
}
expectedHashCount := len(nodes) * replicas
if len(hr.NodesHashList) != expectedHashCount {
t.Errorf("Expected %d hashes, got %d", expectedHashCount, len(hr.NodesHashList))
}
if len(hr.NodeHashToAddr) != expectedHashCount {
t.Errorf("Expected %d mappings, got %d", expectedHashCount, len(hr.NodeHashToAddr))
}
}
func TestHashRing_AddNode(t *testing.T) {
hr := New([]string{"node1", "node2"}, 3)
initialHashCount := len(hr.NodesHashList)
hr.AddNode("node3")
if len(hr.NodeAddrs) != 3 {
t.Errorf("Expected 3 nodes, got %d", len(hr.NodeAddrs))
}
expectedHashCount := initialHashCount + 3
if len(hr.NodesHashList) != expectedHashCount {
t.Errorf("Expected %d hashes, got %d", expectedHashCount, len(hr.NodesHashList))
}
if len(hr.NodeHashToAddr) != expectedHashCount {
t.Errorf("Expected %d mappings, got %d", expectedHashCount, len(hr.NodeHashToAddr))
}
}
func TestHashRing_RemoveNode(t *testing.T) {
hr := New([]string{"node1", "node2", "node3"}, 3)
initialHashCount := len(hr.NodesHashList)
hr.RemoveNode("node2")
if len(hr.NodeAddrs) != 3 {
t.Errorf("Expected 3 nodes, got %d", len(hr.NodeAddrs))
}
expectedHashCount := initialHashCount - 3
if len(hr.NodesHashList) != expectedHashCount {
t.Errorf("Expected %d hashes, got %d", expectedHashCount, len(hr.NodesHashList))
}
if len(hr.NodeHashToAddr) != expectedHashCount {
t.Errorf("Expected %d mappings, got %d", expectedHashCount, len(hr.NodeHashToAddr))
}
}
func TestHashRing_findNextBiggestHash(t *testing.T) {
hr := New([]string{"node1", "node2"}, 1)
tests := []struct {
name string
lookup uint32
expected uint32
}{
{"Exact match", hr.NodesHashList[0], hr.NodesHashList[1]},
{"Between hashes", (hr.NodesHashList[0] + hr.NodesHashList[1]) / 2, hr.NodesHashList[1]},
{"Wrap around", hr.NodesHashList[1] + 1, hr.NodesHashList[0]},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := hr.findNextBiggestHash(tt.lookup)
if result != tt.expected {
t.Errorf("Expected %d, got %d", tt.expected, result)
}
})
}
}
func TestHashRing_GetNodeAddrForKey(t *testing.T) {
nodes := []string{"node1", "node2", "node3"}
hr := New(nodes, 1)
for i := 0; i < 100; i++ {
key := fmt.Sprintf("key%d", i)
node := hr.GetNodeForKey(key)
if !slices.Contains(nodes, node) {
t.Errorf("Got unexpected node %s for key %s", node, key)
}
}
}