|
|
|
@ -15,21 +15,56 @@ package testutil
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"net"
|
|
|
|
|
"sync"
|
|
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
usedPorts []int
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// RandomUnprivilegedPort returns valid unprivileged random port number which can be used for testing.
|
|
|
|
|
func RandomUnprivilegedPort(t *testing.T) int {
|
|
|
|
|
t.Helper()
|
|
|
|
|
mu.Lock()
|
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
|
|
|
|
|
port, err := getPort()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for portWasUsed(port) {
|
|
|
|
|
port, err = getPort()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
usedPorts = append(usedPorts, port)
|
|
|
|
|
|
|
|
|
|
return port
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func portWasUsed(port int) bool {
|
|
|
|
|
for _, usedPort := range usedPorts {
|
|
|
|
|
if port == usedPort {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPort() (int, error) {
|
|
|
|
|
listener, err := net.Listen("tcp", ":0")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Listening on random port: %v", err)
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := listener.Close(); err != nil {
|
|
|
|
|
t.Fatalf("Closing listener: %v", err)
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return listener.Addr().(*net.TCPAddr).Port
|
|
|
|
|
return listener.Addr().(*net.TCPAddr).Port, nil
|
|
|
|
|
}
|
|
|
|
|