chore: consolidate various randomPort() implementations (#12362)

Consolidates our existing randomPort() implementations to package testutil
This commit is contained in:
Cian Johnston 2024-02-29 12:51:44 +00:00 committed by GitHub
parent 4f87ba46f9
commit eba8cd7c07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 52 additions and 42 deletions

View File

@ -8,7 +8,6 @@ import (
"errors"
"fmt"
"io"
"math/rand"
"net"
"net/http"
"net/http/httptest"
@ -838,7 +837,7 @@ func TestAgent_TCPRemoteForwarding(t *testing.T) {
var ll net.Listener
var err error
for {
randomPort = pickRandomPort()
randomPort = testutil.RandomPortNoListen(t)
addr := net.TCPAddrFromAddrPort(netip.AddrPortFrom(localhost, randomPort))
ll, err = sshClient.ListenTCP(addr)
if err != nil {
@ -2666,20 +2665,6 @@ func (s *syncWriter) Write(p []byte) (int, error) {
return s.w.Write(p)
}
// pickRandomPort picks a random port number for the ephemeral range. We do this entirely randomly
// instead of opening a listener and closing it to find a port that is likely to be free, since
// sometimes the OS reallocates the port very quickly.
func pickRandomPort() uint16 {
const (
// Overlap of windows, linux in https://en.wikipedia.org/wiki/Ephemeral_port
min = 49152
max = 60999
)
n := max - min
x := rand.Intn(n) //nolint: gosec
return uint16(min + x)
}
// echoOnce accepts a single connection, reads 4 bytes and echos them back
func echoOnce(t *testing.T, ll net.Listener) {
t.Helper()

View File

@ -937,22 +937,13 @@ func TestServer(t *testing.T) {
t.Run("Prometheus", func(t *testing.T) {
t.Parallel()
randomPort := func(t *testing.T) int {
random, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
_ = random.Close()
tcpAddr, valid := random.Addr().(*net.TCPAddr)
require.True(t, valid)
return tcpAddr.Port
}
t.Run("DBMetricsDisabled", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()
randPort := randomPort(t)
randPort := testutil.RandomPort(t)
inv, cfg := clitest.New(t,
"server",
"--in-memory",
@ -1008,7 +999,7 @@ func TestServer(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()
randPort := randomPort(t)
randPort := testutil.RandomPort(t)
inv, cfg := clitest.New(t,
"server",
"--in-memory",

View File

@ -4,7 +4,6 @@ import (
"bufio"
"context"
"fmt"
"net"
"net/http"
"strings"
"testing"
@ -170,7 +169,7 @@ func TestProvisionerDaemon_SessionToken(t *testing.T) {
t.Run("PrometheusEnabled", func(t *testing.T) {
t.Parallel()
prometheusPort := randomPort(t)
prometheusPort := testutil.RandomPort(t)
// Configure CLI client
client, admin := coderdenttest.New(t, &coderdenttest.Options{
@ -242,13 +241,3 @@ func TestProvisionerDaemon_SessionToken(t *testing.T) {
require.True(t, hasPromHTTP, "Prometheus HTTP metrics are missing")
})
}
// randomPort is a helper function to find a free random port, for instance to spawn Prometheus endpoint.
func randomPort(t *testing.T) int {
random, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
_ = random.Close()
tcpAddr, valid := random.Addr().(*net.TCPAddr)
require.True(t, valid)
return tcpAddr.Port
}

View File

@ -63,7 +63,7 @@ func Test_Headers(t *testing.T) {
func TestWorkspaceProxy_Server_PrometheusEnabled(t *testing.T) {
t.Parallel()
prometheusPort := randomPort(t)
prometheusPort := testutil.RandomPort(t)
var wg sync.WaitGroup
wg.Add(1)
@ -96,7 +96,7 @@ func TestWorkspaceProxy_Server_PrometheusEnabled(t *testing.T) {
"--primary-access-url", srv.URL,
"--proxy-session-token", "test-token",
"--access-url", "http://foobar:3001",
"--http-address", fmt.Sprintf("127.0.0.1:%d", randomPort(t)),
"--http-address", fmt.Sprintf("127.0.0.1:%d", testutil.RandomPort(t)),
"--prometheus-enable",
"--prometheus-address", fmt.Sprintf("127.0.0.1:%d", prometheusPort),
)

View File

@ -22,7 +22,7 @@ func TestServer(t *testing.T) {
var root cli.RootCmd
cmd, err := root.Command(root.EnterpriseSubcommands())
require.NoError(t, err)
port := randomPort(t)
port := testutil.RandomPort(t)
inv, _ := clitest.NewWithCommand(t, cmd,
"server",
"--in-memory",

45
testutil/port.go Normal file
View File

@ -0,0 +1,45 @@
package testutil
import (
"math/rand"
"net"
"sync"
"testing"
"time"
"github.com/stretchr/testify/require"
)
var (
// nolint:gosec // not used for cryptography
rnd = rand.New(rand.NewSource(time.Now().Unix()))
rndMu sync.Mutex
)
// RandomPort is a helper function to find a free random port.
// Note that the OS may reallocate the port very quickly, so
// this is not _guaranteed_.
func RandomPort(t *testing.T) int {
random, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err, "failed to listen on localhost")
_ = random.Close()
tcpAddr, valid := random.Addr().(*net.TCPAddr)
require.True(t, valid, "random port address is not a *net.TCPAddr?!")
return tcpAddr.Port
}
// RandomPortNoListen returns a random port in the ephemeral port range.
// Does not attempt to listen and close to find a port as the OS may
// reallocate the port very quickly.
func RandomPortNoListen(*testing.T) uint16 {
const (
// Overlap of windows, linux in https://en.wikipedia.org/wiki/Ephemeral_port
min = 49152
max = 60999
)
n := max - min
rndMu.Lock()
x := rnd.Intn(n)
rndMu.Unlock()
return uint16(min + x)
}