mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-07-31 04:23:34 +00:00
* test: keep mini-allocated ports below the ephemeral floor Allocated ports could land in 32768-55000, so a transient outbound dial during mini startup (volume->master gRPC, etc.) could grab an allocated port as its source port before the filer bound it, failing with "bind: address already in use". Cap the range so port+GrpcPortOffset stays under 32768. * test: derive mini port cap from the ephemeral floor constant Name the 32768 floor once and compute miniPortMax as floor-GrpcPortOffset so the cap tracks the offset; reuse the constant in the regression test.
74 lines
2.5 KiB
Go
74 lines
2.5 KiB
Go
package testutil
|
|
|
|
import "testing"
|
|
|
|
// AllocateMiniPorts must never hand out a port that weed mini will reserve
|
|
// for one of its default services (or that default's gRPC offset). A real
|
|
// failure: Filer was given 33646 (Admin default 23646 + GrpcPortOffset),
|
|
// which mini then refused as "reserved for gRPC calculation".
|
|
func TestAllocateMiniPortsAvoidsMiniDefaults(t *testing.T) {
|
|
reserved := reservedMiniPorts()
|
|
for iter := 0; iter < 200; iter++ {
|
|
ports, err := AllocateMiniPorts(4)
|
|
if err != nil {
|
|
t.Fatalf("iter %d: AllocateMiniPorts: %v", iter, err)
|
|
}
|
|
for _, p := range ports {
|
|
if reserved[p] {
|
|
t.Fatalf("iter %d: allocated port %d is a mini default (or gRPC offset)", iter, p)
|
|
}
|
|
if reserved[p+GrpcPortOffset] {
|
|
t.Fatalf("iter %d: allocated port %d has gRPC offset %d colliding with a mini default",
|
|
iter, p, p+GrpcPortOffset)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// AllocateMiniPorts must keep every port it hands out, and that port's gRPC
|
|
// counterpart, below 32768 - the Linux default ip_local_port_range floor.
|
|
// A real failure: filer was allocated 44204, then lost the bind to a transient
|
|
// outbound connection that had grabbed 44204 as an ephemeral source port
|
|
// during mini startup ("bind: address already in use").
|
|
func TestAllocateMiniPortsBelowEphemeralFloor(t *testing.T) {
|
|
const ephemeralFloor = linuxEphemeralPortFloor
|
|
for iter := 0; iter < 200; iter++ {
|
|
ports, err := AllocateMiniPorts(4)
|
|
if err != nil {
|
|
t.Fatalf("iter %d: AllocateMiniPorts: %v", iter, err)
|
|
}
|
|
for _, p := range ports {
|
|
if p+GrpcPortOffset >= ephemeralFloor {
|
|
t.Fatalf("iter %d: port %d (gRPC %d) reaches the ephemeral range floor %d",
|
|
iter, p, p+GrpcPortOffset, ephemeralFloor)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAllocatePortSetNoGrpcCollision(t *testing.T) {
|
|
// Run a few iterations to catch the OS-recycles-just-closed-port race
|
|
// that previously hit regular ports when the mini gRPC offset was freed
|
|
// between AllocateMiniPorts and AllocatePorts calls.
|
|
for iter := 0; iter < 20; iter++ {
|
|
mini, regular, err := AllocatePortSet(1, 3)
|
|
if err != nil {
|
|
t.Fatalf("iter %d: AllocatePortSet: %v", iter, err)
|
|
}
|
|
if len(mini) != 1 || len(regular) != 3 {
|
|
t.Fatalf("iter %d: unexpected counts mini=%d regular=%d", iter, len(mini), len(regular))
|
|
}
|
|
reserved := map[int]bool{
|
|
mini[0]: true,
|
|
mini[0] + GrpcPortOffset: true,
|
|
}
|
|
for _, p := range regular {
|
|
if reserved[p] {
|
|
t.Fatalf("iter %d: regular port %d collides with mini pair %d/%d",
|
|
iter, p, mini[0], mini[0]+GrpcPortOffset)
|
|
}
|
|
reserved[p] = true
|
|
}
|
|
}
|
|
}
|