Add dbx library: PostgreSQL cluster with master/replica routing, retry, health checking
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
73
balancer_test.go
Normal file
73
balancer_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package dbx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRoundRobinBalancer_Empty(t *testing.T) {
|
||||
b := NewRoundRobinBalancer()
|
||||
if n := b.Next(nil); n != nil {
|
||||
t.Errorf("expected nil for empty slice, got %v", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundRobinBalancer_AllHealthy(t *testing.T) {
|
||||
b := NewRoundRobinBalancer()
|
||||
nodes := makeTestNodes("a", "b", "c")
|
||||
|
||||
seen := map[string]int{}
|
||||
for range 30 {
|
||||
n := b.Next(nodes)
|
||||
if n == nil {
|
||||
t.Fatal("unexpected nil")
|
||||
}
|
||||
seen[n.name]++
|
||||
}
|
||||
|
||||
if len(seen) != 3 {
|
||||
t.Errorf("expected 3 distinct nodes, got %d", len(seen))
|
||||
}
|
||||
for name, count := range seen {
|
||||
if count != 10 {
|
||||
t.Errorf("node %s hit %d times, expected 10", name, count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundRobinBalancer_SkipsUnhealthy(t *testing.T) {
|
||||
b := NewRoundRobinBalancer()
|
||||
nodes := makeTestNodes("a", "b", "c")
|
||||
nodes[1].healthy.Store(false) // b is down
|
||||
|
||||
for range 20 {
|
||||
n := b.Next(nodes)
|
||||
if n == nil {
|
||||
t.Fatal("unexpected nil")
|
||||
}
|
||||
if n.name == "b" {
|
||||
t.Error("should not return unhealthy node b")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundRobinBalancer_AllUnhealthy(t *testing.T) {
|
||||
b := NewRoundRobinBalancer()
|
||||
nodes := makeTestNodes("a", "b")
|
||||
for _, n := range nodes {
|
||||
n.healthy.Store(false)
|
||||
}
|
||||
|
||||
if n := b.Next(nodes); n != nil {
|
||||
t.Errorf("expected nil when all unhealthy, got %v", n.name)
|
||||
}
|
||||
}
|
||||
|
||||
func makeTestNodes(names ...string) []*Node {
|
||||
nodes := make([]*Node, len(names))
|
||||
for i, name := range names {
|
||||
n := &Node{name: name}
|
||||
n.healthy.Store(true)
|
||||
nodes[i] = n
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
Reference in New Issue
Block a user