diff --git a/test/integration/vmcp/helpers/vmcp_server.go b/test/integration/vmcp/helpers/vmcp_server.go index 7805e1047a..3416b7c65c 100644 --- a/test/integration/vmcp/helpers/vmcp_server.go +++ b/test/integration/vmcp/helpers/vmcp_server.go @@ -5,7 +5,6 @@ package helpers import ( "context" - "net" "testing" "time" @@ -122,25 +121,18 @@ func WithSessionTTL(ttl time.Duration) VMCPServerOption { } } -// getFreePort returns an available TCP port on localhost. -func getFreePort(tb testing.TB) int { - tb.Helper() - - listener, err := net.Listen("tcp", "127.0.0.1:0") - require.NoError(tb, err, "failed to get free port") - defer func() { _ = listener.Close() }() - - addr, ok := listener.Addr().(*net.TCPAddr) - if !ok { - tb.Fatalf("failed to get TCP address from listener") - } - return addr.Port -} - // NewVMCPServer creates a vMCP server for testing using the Serve path (core.New + // Serve). The server is automatically started and ready when this function returns. // Use functional options to customize behavior. // +// The server binds an OS-assigned port (ServerConfig.Port is 0) and holds that +// listener for its lifetime, so callers MUST read the address back from the +// returned server's Address() rather than assuming a port. Address() reports the +// bound port only once the server is ready, which this function waits for before +// returning. Do not pre-select a port here by binding and closing a probe +// listener: that releases the port, and any of the parallel tests in this suite +// can claim it before the server rebinds (#6034). +// // The Serve path is used (rather than the legacy server.New path) so that // integration tests exercise the production code path that routes tool/resource // calls through core.VMCP. This is required for testing per-request @@ -197,7 +189,7 @@ func NewVMCPServer( Name: "test-vmcp", Version: "1.0.0", Host: "127.0.0.1", - Port: getFreePort(tb), + Port: 0, // OS-assigned; see the note on NewVMCPServer EndpointPath: "/mcp", SessionTTL: 30 * time.Minute, AuthMiddleware: auth.AnonymousMiddleware,