[proxy] Strip only a gateway's own namespace before matching a model

Three open review findings.

The discovery filter treated every slash in a listed id as a gateway prefix
and matched the tail against the policy. A self-hosted id carries slashes of
its own, and an upstream may scope ids per tenant, so "tenant-b/claude-sonnet-5"
matched a permitted "claude-sonnet-5" and reached the picker — a model the
policy never named, and one the guardrail denies on sight, since enforcement
compares the id as written. Strip only the namespaces a gateway is known to
prepend, taken from the first slash rather than the last.

The e2e retry loops slept between attempts without watching the context, so a
cancelled run kept retrying calls that fail instantly and spent its remaining
window sleeping between them. They now stop when the context is done.

The streamed provider's setup key outlived its test: deleting the group does
not delete the key that auto-joins it.
This commit is contained in:
mlsmaycon
2026-08-23 06:35:27 +00:00
parent a02aa16cae
commit acfad1a384
5 changed files with 80 additions and 11 deletions
+9 -3
View File
@@ -163,7 +163,9 @@ func chatOnce(t *testing.T, ctx context.Context, env pricedEnv, model, sessionID
break
}
}
time.Sleep(5 * time.Second)
if !waitBeforeRetry(ctx, 5*time.Second) {
break
}
}
require.Equal(t, 200, code,
"chat for %s must return 200; body: %s\n=== proxy logs ===\n%s", model, body, env.proxy.Logs(context.Background()))
@@ -430,7 +432,9 @@ func TestPriceChangeUpdatesRecordedCost(t *testing.T) {
lastSession = fmt.Sprintf("e2e-session-reprice-b-%d", time.Now().UnixNano())
code, _, cerr := env.client.Chat(ctx, env.endpoint, env.proxyIP, harness.WireChat, customModel, "Reply with exactly: pong", lastSession)
if cerr != nil || code != 200 {
time.Sleep(5 * time.Second)
if !waitBeforeRetry(ctx, 5*time.Second) {
break
}
continue
}
row, ok := lookupAccessLogBySession(ctx, lastSession, repriceIngestWindow)
@@ -448,7 +452,9 @@ func TestPriceChangeUpdatesRecordedCost(t *testing.T) {
}
// Still priced at the old rate — the push hasn't landed yet; retry.
lastCost, sawRow = row.InputCostUsd, true
time.Sleep(5 * time.Second)
if !waitBeforeRetry(ctx, 5*time.Second) {
break
}
}
lastSeen := "no row was ever read"
if sawRow {
+16
View File
@@ -54,3 +54,19 @@ func run(m *testing.M) int {
return m.Run()
}
// waitBeforeRetry pauses between attempts of a polling loop and reports
// whether the caller should keep going. A cancelled context ends the loop
// where a plain sleep would keep retrying against it: every call fails
// instantly once ctx is done, so the loop would spend its whole remaining
// window sleeping between failures nobody is waiting for any more.
func waitBeforeRetry(ctx context.Context, d time.Duration) bool {
timer := time.NewTimer(d)
defer timer.Stop()
select {
case <-ctx.Done():
return false
case <-timer.C:
return true
}
}
+6 -1
View File
@@ -129,6 +129,9 @@ func provisionStreamingProvider(t *testing.T, ctx context.Context, catalogID str
Ephemeral: &ephemeral,
})
require.NoError(t, err, "mint setup key")
// Deleting the group does not delete the key it auto-joins, so the key
// needs a cleanup of its own.
t.Cleanup(func() { _ = srv.API().SetupKeys.Delete(context.Background(), sk.Id) })
require.NotEmpty(t, sk.Key, "setup key plaintext")
dummyKey := "sk-stream-e2e"
@@ -195,7 +198,9 @@ func chatStreamUntil(t *testing.T, ctx context.Context, env pricedEnv, kind, mod
break
}
}
time.Sleep(5 * time.Second)
if !waitBeforeRetry(ctx, 5*time.Second) {
break
}
}
if code != 200 {
t.Logf("=== proxy logs ===\n%s", env.proxy.Logs(context.Background()))