test(routing): de-flake TestRoutingPodEndToEnd
- Random port via net.Listen(":0") replaces hardcoded 33310 (was the
primary failure mode under parallel test load).
- Bump waitForPort deadline 5s → 30s — `go build` under -race can exceed
5s on a loaded machine.
- Replace osPath() (always returned empty PATH because exec.Command("env").Env
is the *child's* env, not the parent's) with explicit PATH+HOME via
os.Getenv. Don't inherit full env: would leak ROUTING_MCP_TOKEN from the
parent shell and flip the routing pod into auth-required mode, breaking
the test.
Closes #15. Verified: 10 cold-cache test runs pass, 3 consecutive task check
runs pass.
This commit is contained in:
@@ -4,9 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -42,28 +45,33 @@ func TestRoutingPodEndToEnd(t *testing.T) {
|
|||||||
}))
|
}))
|
||||||
defer brain.Close()
|
defer brain.Close()
|
||||||
|
|
||||||
|
port := freePort(t)
|
||||||
|
addr := "127.0.0.1:" + port
|
||||||
|
baseURL := "http://" + addr
|
||||||
|
|
||||||
bin := buildRouting(t)
|
bin := buildRouting(t)
|
||||||
cmd := exec.Command(bin)
|
cmd := exec.Command(bin)
|
||||||
cmd.Env = append(cmd.Env,
|
cmd.Env = []string{
|
||||||
"ROUTING_PORT=33310",
|
"ROUTING_PORT=" + port,
|
||||||
"LITELLM_BASE_URL="+llm.URL,
|
"LITELLM_BASE_URL=" + llm.URL,
|
||||||
"LITELLM_API_KEY=stub",
|
"LITELLM_API_KEY=stub",
|
||||||
"BRAIN_URL="+brain.URL,
|
"BRAIN_URL=" + brain.URL,
|
||||||
"SUPERVISOR_CONFIG_DIR=../../config/supervisor",
|
"SUPERVISOR_CONFIG_DIR=../../config/supervisor",
|
||||||
"PATH="+osPath(),
|
"PATH=" + os.Getenv("PATH"),
|
||||||
)
|
"HOME=" + os.Getenv("HOME"),
|
||||||
|
}
|
||||||
require.NoError(t, cmd.Start())
|
require.NoError(t, cmd.Start())
|
||||||
t.Cleanup(func() { _ = cmd.Process.Kill() })
|
t.Cleanup(func() { _ = cmd.Process.Kill() })
|
||||||
|
|
||||||
require.NoError(t, waitForPort(t, "127.0.0.1:33310", 5*time.Second))
|
require.NoError(t, waitForPort(t, addr, 30*time.Second))
|
||||||
|
|
||||||
resp := mcpCall(t, "http://127.0.0.1:33310/mcp", `{"jsonrpc":"2.0","id":1,"method":"tools/list"}`)
|
resp := mcpCall(t, baseURL+"/mcp", `{"jsonrpc":"2.0","id":1,"method":"tools/list"}`)
|
||||||
assert.Contains(t, resp, `"review"`)
|
assert.Contains(t, resp, `"review"`)
|
||||||
assert.Contains(t, resp, `"debug"`)
|
assert.Contains(t, resp, `"debug"`)
|
||||||
assert.Contains(t, resp, `"retrospective"`)
|
assert.Contains(t, resp, `"retrospective"`)
|
||||||
assert.Contains(t, resp, `"trainer"`)
|
assert.Contains(t, resp, `"trainer"`)
|
||||||
|
|
||||||
resp = mcpCall(t, "http://127.0.0.1:33310/mcp", `{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"review","arguments":{"project_root":"/tmp","files":["README.md"]}}}`)
|
resp = mcpCall(t, baseURL+"/mcp", `{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"review","arguments":{"project_root":"/tmp","files":["README.md"]}}}`)
|
||||||
_ = resp // shape varies by skill; we only need a 200
|
_ = resp // shape varies by skill; we only need a 200
|
||||||
|
|
||||||
// Wait briefly for the async session_log to land.
|
// Wait briefly for the async session_log to land.
|
||||||
@@ -113,11 +121,15 @@ func mcpCall(t *testing.T, url, body string) string {
|
|||||||
return string(raw)
|
return string(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func osPath() string {
|
// freePort grabs an OS-assigned TCP port and releases it. There is a small
|
||||||
for _, e := range append([]string{}, exec.Command("env").Env...) {
|
// race window before the subprocess re-binds it, but it is acceptable for
|
||||||
if strings.HasPrefix(e, "PATH=") {
|
// test isolation against a hardcoded port colliding with another test or
|
||||||
return strings.TrimPrefix(e, "PATH=")
|
// stray process.
|
||||||
}
|
func freePort(t *testing.T) string {
|
||||||
}
|
t.Helper()
|
||||||
return "/usr/bin:/bin"
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
|
require.NoError(t, err)
|
||||||
|
port := l.Addr().(*net.TCPAddr).Port
|
||||||
|
require.NoError(t, l.Close())
|
||||||
|
return strconv.Itoa(port)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user