package pool import ( "sync" "testing" ) func TestPortAllocator_AllocateRelease(t *testing.T) { pa := NewPortAllocator(8500, 8502) p1, err := pa.Allocate() if err != nil { t.Fatal(err) } p2, err := pa.Allocate() if err != nil { t.Fatal(err) } p3, err := pa.Allocate() if err != nil { t.Fatal(err) } // All three ports should be distinct if p1 == p2 || p2 == p3 || p1 == p3 { t.Fatalf("expected distinct ports: %d, %d, %d", p1, p2, p3) } // Exhausted _, err = pa.Allocate() if err == nil { t.Fatal("expected error when exhausted") } // Release and re-allocate pa.Release(p2) p4, err := pa.Allocate() if err != nil { t.Fatal(err) } if p4 != p2 { t.Fatalf("expected released port %d, got %d", p2, p4) } } func TestPortAllocator_Concurrent(t *testing.T) { pa := NewPortAllocator(8500, 8599) var wg sync.WaitGroup allocated := make(chan int, 100) for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() p, err := pa.Allocate() if err != nil { return } allocated <- p }() } wg.Wait() close(allocated) seen := make(map[int]bool) for p := range allocated { if seen[p] { t.Fatalf("duplicate port %d", p) } seen[p] = true } if len(seen) != 100 { t.Fatalf("expected 100 ports, got %d", len(seen)) } }