mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-13 17:48:29 +02:00
The replica-placement rule (data-center/rack/same-node limits plus host anti-affinity) existed three times: the shell's satisfyReplicaPlacement/isGoodMove used by volume.balance, fix.replication, and tier.move, and a line-for-line port in the maintenance balance worker. Move the canonical logic into weed/topology/balancer on a shared Location type; the shell and worker keep thin adapters that convert their own location representation and call it. Behavior is unchanged (the shared IsGoodMove keeps the shell's reject-move-to-self guard, and all four replica test suites pass).
37 lines
1.5 KiB
Go
37 lines
1.5 KiB
Go
package balancer
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/super_block"
|
|
)
|
|
|
|
func loc(dc, rack, node string) Location {
|
|
return Location{DataCenter: dc, Rack: rack, NodeID: node}
|
|
}
|
|
|
|
// When a node abnormally holds more than one replica of a volume, moving one of
|
|
// them off must keep the other in the after-move set, so the placement check
|
|
// still sees the rack's true occupancy.
|
|
func TestIsGoodMove_OverReplicatedSourceKeepsOtherReplica(t *testing.T) {
|
|
rp, err := super_block.NewReplicaPlacementFromString("001") // up to 2 copies in a rack
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// n1 abnormally holds two replicas; n2 holds a third — all in rack r1.
|
|
existing := []Location{loc("dc1", "r1", "n1"), loc("dc1", "r1", "n1"), loc("dc1", "r1", "n2")}
|
|
|
|
// Moving ONE replica off n1 onto a new node n3 in r1 must be rejected: r1 would
|
|
// still hold two replicas (the retained n1 and n2), at the SameRackCount limit.
|
|
if IsGoodMove(rp, existing, "n1", loc("dc1", "r1", "n3")) {
|
|
t.Error("expected reject: moving one replica off an over-replicated node must keep its other replica in the rack count")
|
|
}
|
|
|
|
// The normal case is unaffected: two replicas correctly in r1, move one to a
|
|
// third node in r1 — still within the SameRackCount=1 (two-per-rack) limit.
|
|
normal := []Location{loc("dc1", "r1", "n1"), loc("dc1", "r1", "n2")}
|
|
if !IsGoodMove(rp, normal, "n1", loc("dc1", "r1", "n3")) {
|
|
t.Error("expected allow: a normal move within the rack limit")
|
|
}
|
|
}
|