mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-15 01:48:49 +00:00
195 lines
5.0 KiB
Go
195 lines
5.0 KiB
Go
package rqlite
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestPortManager_AllocatePortPair(t *testing.T) {
|
|
pm := NewPortManager(
|
|
PortRange{Start: 5001, End: 5010},
|
|
PortRange{Start: 7001, End: 7010},
|
|
)
|
|
|
|
ports, err := pm.AllocatePortPair("testdb")
|
|
if err != nil {
|
|
t.Fatalf("Failed to allocate port pair: %v", err)
|
|
}
|
|
|
|
// Verify HTTP port in range
|
|
if ports.HTTPPort < 5001 || ports.HTTPPort > 5010 {
|
|
t.Errorf("HTTP port %d out of range [5001-5010]", ports.HTTPPort)
|
|
}
|
|
|
|
// Verify Raft port in range
|
|
if ports.RaftPort < 7001 || ports.RaftPort > 7010 {
|
|
t.Errorf("Raft port %d out of range [7001-7010]", ports.RaftPort)
|
|
}
|
|
|
|
// Verify ports are different
|
|
if ports.HTTPPort == ports.RaftPort {
|
|
t.Error("HTTP and Raft ports should be different")
|
|
}
|
|
}
|
|
|
|
func TestPortManager_ReleasePortPair(t *testing.T) {
|
|
pm := NewPortManager(
|
|
PortRange{Start: 5001, End: 5010},
|
|
PortRange{Start: 7001, End: 7010},
|
|
)
|
|
|
|
// Allocate
|
|
ports, err := pm.AllocatePortPair("testdb")
|
|
if err != nil {
|
|
t.Fatalf("Failed to allocate port pair: %v", err)
|
|
}
|
|
|
|
// Release
|
|
pm.ReleasePortPair(ports)
|
|
|
|
// Should be able to allocate again
|
|
ports2, err := pm.AllocatePortPair("testdb2")
|
|
if err != nil {
|
|
t.Fatalf("Failed to allocate after release: %v", err)
|
|
}
|
|
|
|
// Might get same ports back (that's OK)
|
|
if ports2.HTTPPort == 0 || ports2.RaftPort == 0 {
|
|
t.Error("Got zero ports after release and reallocation")
|
|
}
|
|
}
|
|
|
|
func TestPortManager_IsPortAllocated(t *testing.T) {
|
|
pm := NewPortManager(
|
|
PortRange{Start: 5001, End: 5010},
|
|
PortRange{Start: 7001, End: 7010},
|
|
)
|
|
|
|
// Initially not allocated
|
|
if pm.IsPortAllocated(5001) {
|
|
t.Error("Port should not be allocated initially")
|
|
}
|
|
|
|
// Allocate
|
|
ports, err := pm.AllocatePortPair("testdb")
|
|
if err != nil {
|
|
t.Fatalf("Failed to allocate: %v", err)
|
|
}
|
|
|
|
// Should be allocated now
|
|
if !pm.IsPortAllocated(ports.HTTPPort) {
|
|
t.Error("HTTP port should be allocated")
|
|
}
|
|
if !pm.IsPortAllocated(ports.RaftPort) {
|
|
t.Error("Raft port should be allocated")
|
|
}
|
|
|
|
// Release
|
|
pm.ReleasePortPair(ports)
|
|
|
|
// Should not be allocated anymore
|
|
if pm.IsPortAllocated(ports.HTTPPort) {
|
|
t.Error("HTTP port should not be allocated after release")
|
|
}
|
|
if pm.IsPortAllocated(ports.RaftPort) {
|
|
t.Error("Raft port should not be allocated after release")
|
|
}
|
|
}
|
|
|
|
func TestPortManager_AllocateSpecificPorts(t *testing.T) {
|
|
pm := NewPortManager(
|
|
PortRange{Start: 5001, End: 5010},
|
|
PortRange{Start: 7001, End: 7010},
|
|
)
|
|
|
|
specificPorts := PortPair{HTTPPort: 5005, RaftPort: 7005}
|
|
|
|
// Allocate specific ports
|
|
err := pm.AllocateSpecificPorts("testdb", specificPorts)
|
|
if err != nil {
|
|
t.Fatalf("Failed to allocate specific ports: %v", err)
|
|
}
|
|
|
|
// Verify allocated
|
|
if !pm.IsPortAllocated(5005) {
|
|
t.Error("Port 5005 should be allocated")
|
|
}
|
|
if !pm.IsPortAllocated(7005) {
|
|
t.Error("Port 7005 should be allocated")
|
|
}
|
|
|
|
// Try to allocate same ports again - should fail
|
|
err = pm.AllocateSpecificPorts("testdb2", specificPorts)
|
|
if err == nil {
|
|
t.Error("Expected error when allocating already-allocated ports")
|
|
}
|
|
}
|
|
|
|
func TestPortManager_Exhaustion(t *testing.T) {
|
|
// Very small range
|
|
pm := NewPortManager(
|
|
PortRange{Start: 5001, End: 5002}, // Only 2 ports
|
|
PortRange{Start: 7001, End: 7002}, // Only 2 ports
|
|
)
|
|
|
|
// Allocate first pair (uses 2 ports)
|
|
_, err := pm.AllocatePortPair("db1")
|
|
if err != nil {
|
|
t.Fatalf("First allocation should succeed: %v", err)
|
|
}
|
|
|
|
// Try to allocate second pair - might fail due to limited ports
|
|
// Note: This test is probabilistic due to random selection
|
|
// In a real scenario with only 2 ports per range, we can only fit 1 database
|
|
_, err = pm.AllocatePortPair("db2")
|
|
// We expect this to eventually fail after retries
|
|
// The actual behavior depends on random selection
|
|
|
|
// For a more deterministic test, allocate specific ports
|
|
pm2 := NewPortManager(
|
|
PortRange{Start: 5001, End: 5002},
|
|
PortRange{Start: 7001, End: 7002},
|
|
)
|
|
|
|
_ = pm2.AllocateSpecificPorts("db1", PortPair{HTTPPort: 5001, RaftPort: 7001})
|
|
_ = pm2.AllocateSpecificPorts("db2", PortPair{HTTPPort: 5002, RaftPort: 7002})
|
|
|
|
// Now exhausted
|
|
err = pm2.AllocateSpecificPorts("db3", PortPair{HTTPPort: 5001, RaftPort: 7001})
|
|
if err == nil {
|
|
t.Error("Expected error when ports exhausted")
|
|
}
|
|
}
|
|
|
|
func TestPortManager_MultipleDatabases(t *testing.T) {
|
|
pm := NewPortManager(
|
|
PortRange{Start: 5001, End: 5020},
|
|
PortRange{Start: 7001, End: 7020},
|
|
)
|
|
|
|
databases := []string{"db1", "db2", "db3", "db4", "db5"}
|
|
allocatedPorts := make(map[int]bool)
|
|
|
|
for _, db := range databases {
|
|
ports, err := pm.AllocatePortPair(db)
|
|
if err != nil {
|
|
t.Fatalf("Failed to allocate for %s: %v", db, err)
|
|
}
|
|
|
|
// Verify no port conflicts
|
|
if allocatedPorts[ports.HTTPPort] {
|
|
t.Errorf("HTTP port %d already allocated", ports.HTTPPort)
|
|
}
|
|
if allocatedPorts[ports.RaftPort] {
|
|
t.Errorf("Raft port %d already allocated", ports.RaftPort)
|
|
}
|
|
|
|
allocatedPorts[ports.HTTPPort] = true
|
|
allocatedPorts[ports.RaftPort] = true
|
|
}
|
|
|
|
// Should have allocated 10 unique ports (5 HTTP + 5 Raft)
|
|
if len(allocatedPorts) != 10 {
|
|
t.Errorf("Expected 10 unique ports, got %d", len(allocatedPorts))
|
|
}
|
|
}
|