chore(cli): avoid use of testutil.RandomPort() in prometheus test (#17297)

Should hopefully fix https://github.com/coder/internal/issues/282

Instead of picking a random port for the prometheus server, listen on
`:0` and read the port from the CLI stdout.
This commit is contained in:
Cian Johnston
2025-04-09 09:20:47 +01:00
committed by GitHub
parent 0e658219b2
commit 8d122aa4ab
2 changed files with 35 additions and 15 deletions

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"net"
"net/http" "net/http"
"net/http/pprof" "net/http/pprof"
"net/url" "net/url"
@ -491,8 +492,6 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
} }
func ServeHandler(ctx context.Context, logger slog.Logger, handler http.Handler, addr, name string) (closeFunc func()) { func ServeHandler(ctx context.Context, logger slog.Logger, handler http.Handler, addr, name string) (closeFunc func()) {
logger.Debug(ctx, "http server listening", slog.F("addr", addr), slog.F("name", name))
// ReadHeaderTimeout is purposefully not enabled. It caused some issues with // ReadHeaderTimeout is purposefully not enabled. It caused some issues with
// websockets over the dev tunnel. // websockets over the dev tunnel.
// See: https://github.com/coder/coder/pull/3730 // See: https://github.com/coder/coder/pull/3730
@ -502,9 +501,15 @@ func ServeHandler(ctx context.Context, logger slog.Logger, handler http.Handler,
Handler: handler, Handler: handler,
} }
go func() { go func() {
err := srv.ListenAndServe() ln, err := net.Listen("tcp", addr)
if err != nil && !xerrors.Is(err, http.ErrServerClosed) { if err != nil {
logger.Error(ctx, "http server listen", slog.F("name", name), slog.Error(err)) logger.Error(ctx, "http server listen", slog.F("name", name), slog.F("addr", addr), slog.Error(err))
return
}
defer ln.Close()
logger.Info(ctx, "http server listening", slog.F("addr", ln.Addr()), slog.F("name", name))
if err := srv.Serve(ln); err != nil && !xerrors.Is(err, http.ErrServerClosed) {
logger.Error(ctx, "http server serve", slog.F("addr", ln.Addr()), slog.F("name", name), slog.Error(err))
} }
}() }()

View File

@ -22,6 +22,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"regexp"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
@ -1217,24 +1218,31 @@ func TestServer(t *testing.T) {
t.Parallel() t.Parallel()
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
randPort := testutil.RandomPort(t) inv, _ := clitest.New(t,
inv, cfg := clitest.New(t,
"server", "server",
"--in-memory", "--in-memory",
"--http-address", ":0", "--http-address", ":0",
"--access-url", "http://example.com", "--access-url", "http://example.com",
"--provisioner-daemons", "1", "--provisioner-daemons", "1",
"--prometheus-enable", "--prometheus-enable",
"--prometheus-address", ":"+strconv.Itoa(randPort), "--prometheus-address", ":0",
// "--prometheus-collect-db-metrics", // disabled by default // "--prometheus-collect-db-metrics", // disabled by default
"--cache-dir", t.TempDir(), "--cache-dir", t.TempDir(),
) )
pty := ptytest.New(t)
inv.Stdout = pty.Output()
inv.Stderr = pty.Output()
clitest.Start(t, inv) clitest.Start(t, inv)
_ = waitAccessURL(t, cfg)
// Wait until we see the prometheus address in the logs.
addrMatchExpr := `http server listening\s+addr=(\S+)\s+name=prometheus`
lineMatch := pty.ExpectRegexMatchContext(ctx, addrMatchExpr)
promAddr := regexp.MustCompile(addrMatchExpr).FindStringSubmatch(lineMatch)[1]
testutil.Eventually(ctx, t, func(ctx context.Context) bool { testutil.Eventually(ctx, t, func(ctx context.Context) bool {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("http://127.0.0.1:%d/metrics", randPort), nil) req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("http://%s/metrics", promAddr), nil)
if err != nil { if err != nil {
t.Logf("error creating request: %s", err.Error()) t.Logf("error creating request: %s", err.Error())
return false return false
@ -1272,24 +1280,31 @@ func TestServer(t *testing.T) {
t.Parallel() t.Parallel()
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
randPort := testutil.RandomPort(t) inv, _ := clitest.New(t,
inv, cfg := clitest.New(t,
"server", "server",
"--in-memory", "--in-memory",
"--http-address", ":0", "--http-address", ":0",
"--access-url", "http://example.com", "--access-url", "http://example.com",
"--provisioner-daemons", "1", "--provisioner-daemons", "1",
"--prometheus-enable", "--prometheus-enable",
"--prometheus-address", ":"+strconv.Itoa(randPort), "--prometheus-address", ":0",
"--prometheus-collect-db-metrics", "--prometheus-collect-db-metrics",
"--cache-dir", t.TempDir(), "--cache-dir", t.TempDir(),
) )
pty := ptytest.New(t)
inv.Stdout = pty.Output()
inv.Stderr = pty.Output()
clitest.Start(t, inv) clitest.Start(t, inv)
_ = waitAccessURL(t, cfg)
// Wait until we see the prometheus address in the logs.
addrMatchExpr := `http server listening\s+addr=(\S+)\s+name=prometheus`
lineMatch := pty.ExpectRegexMatchContext(ctx, addrMatchExpr)
promAddr := regexp.MustCompile(addrMatchExpr).FindStringSubmatch(lineMatch)[1]
testutil.Eventually(ctx, t, func(ctx context.Context) bool { testutil.Eventually(ctx, t, func(ctx context.Context) bool {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("http://127.0.0.1:%d/metrics", randPort), nil) req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("http://%s/metrics", promAddr), nil)
if err != nil { if err != nil {
t.Logf("error creating request: %s", err.Error()) t.Logf("error creating request: %s", err.Error())
return false return false