Files
webui4frpc/internal/cluster/ring_test.go

96 lines
2.6 KiB
Go

package cluster
import (
"testing"
"webui4frpc/internal/store"
)
func newNode(id string, mem float64) Node {
return Node{ID: id, Addr: id + ":7500", Alive: true, Load: Load{MemPct: mem, NetPct: 10}}
}
func TestRingSuccessors(t *testing.T) {
s := &State{}
s.InsertAfter("", newNode("a", 50))
s.InsertAfter("a", newNode("b", 40))
s.InsertAfter("b", newNode("c", 30))
if got, _ := s.AliveSuccessor("a"); got != "b" {
t.Fatalf("succ(a)=%s want b", got)
}
if got, _ := s.AliveSuccessor("c"); got != "a" {
t.Fatalf("succ(c)=%s want a (wrap)", got)
}
s.MarkOffline("b")
if got, _ := s.AliveSuccessor("a"); got != "c" {
t.Fatalf("succ(a) after b down =%s want c", got)
}
if got, _ := s.AlivePredecessor("a"); got != "c" {
t.Fatalf("pred(a)=%s want c", got)
}
}
func TestLowestLoadClaimsTask(t *testing.T) {
s := &State{}
s.InsertAfter("", newNode("a", 90))
s.InsertAfter("a", newNode("b", 20)) // idle
t1 := s.AddPending(store.Local{Name: "l1"}, store.Remote{Name: "r1"}, store.Link{})
low := s.LowestAlive()
if low == nil || low.ID != "b" {
t.Fatalf("lowest = %+v want b", low)
}
// b claims + establishes topology
claimed := s.ClaimPending(t1.ID)
if claimed == nil {
t.Fatal("claim should succeed")
}
if len(s.PendingList()) != 0 {
t.Fatalf("pending after claim = %+v", s.PendingList())
}
s.AddTopology(claimed, "b")
if len(s.TopologyList()) != 1 || s.TopologyList()[0].OwnerID != "b" {
t.Fatalf("topology = %+v", s.TopologyList())
}
}
func TestOfflineReassignTopology(t *testing.T) {
s := &State{}
s.InsertAfter("", newNode("a", 50))
// a establishes two forwards
for _, ln := range []string{"l1", "l2"} {
p := s.AddPending(store.Local{Name: ln}, store.Remote{Name: "r1"}, store.Link{})
s.ClaimPending(p.ID)
s.AddTopology(p, "a")
}
if len(s.TopologyList()) != 2 {
t.Fatalf("topology = %+v", s.TopologyList())
}
// a goes offline: forwards re-attached as pending
reattached := s.OfflineReassign("a")
if len(reattached) != 2 {
t.Fatalf("reattached=%v want 2", reattached)
}
if len(s.TopologyList()) != 0 {
t.Fatalf("topology after reassign = %+v", s.TopologyList())
}
if len(s.PendingList()) != 2 {
t.Fatalf("pending after reassign = %+v", s.PendingList())
}
}
func TestInsertAfterReorders(t *testing.T) {
s := &State{}
s.InsertAfter("", newNode("a", 50))
s.InsertAfter("a", newNode("b", 50))
s.InsertAfter("a", newNode("new", 50)) // new lands after a, b pushed after new
var order []string
for _, n := range s.Nodes {
order = append(order, n.ID)
}
if order[0] != "a" || order[1] != "new" || order[2] != "b" {
t.Fatalf("order = %v want [a new b]", order)
}
}