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 }