Skip to content

test(e2e): add the endpoint x provider x auth mode matrix - #42372

Open
devin-ai-integration[bot] wants to merge 7 commits into
mainfrom
litellm_1790034420_endpoint_matrix_e2e
Open

devin-ai-integration[bot] wants to merge 7 commits into
mainfrom
litellm_1790034420_endpoint_matrix_e2e

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • A bug fixed on /v1/chat/completions keeps living on /v1/messages or /v1/responses
  • Each endpoint test covers its own providers and auth modes, so coverage drifts
  • Adding a provider today means writing a new test per endpoint

How it solves it:

  • One parametrized e2e test: 10 endpoints x 6 providers x 3 auth modes, 135 cells
  • Same request and same assertion in every cell, one red cell names the gap
  • Adding a provider is one Provider catalog entry, no new test code
  • OpenAI and Anthropic cells replay from fixtures: 60 cells in about 20 seconds, zero egress
  • Additive only: no existing endpoint test was touched

User Flow

Before: a developer whose stored-credential Anthropic deployment answers on /v1/chat/completions but fails on /v1/messages has no test that would have caught it before release

  1. An operator sends POST http://localhost:4000/credentials with {"credential_name":"cred-1","credential_values":{"api_key":"..."},"credential_info":{}} and gets {"success":true}
  2. They send POST http://localhost:4000/model/new with {"model_name":"m-1","litellm_params":{"model":"anthropic/claude-haiku-4-5","litellm_credential_name":"cred-1"}} and get back a model_info.id
  3. The developer sends POST http://localhost:4000/v1/chat/completions with {"model":"m-1","messages":[...]} and gets assistant text back
  4. They send POST http://localhost:4000/v1/messages with the same model and messages and get a 500 naming a translation error
  5. Nothing in CI went red before the release, because the stored-credential path was only exercised on /v1/chat/completions

After: the same regression turns exactly one cell red in CI, messages-nonstream-anthropic-stored_credential, before it ships

  1. An operator sends POST http://localhost:4000/credentials with {"credential_name":"cred-1","credential_values":{"api_key":"..."},"credential_info":{}} and gets {"success":true}
  2. They send POST http://localhost:4000/model/new with {"model_name":"m-1","litellm_params":{"model":"anthropic/claude-haiku-4-5","litellm_credential_name":"cred-1"}} and get back a model_info.id
  3. The developer sends POST http://localhost:4000/v1/chat/completions with {"model":"m-1","messages":[...]} and gets assistant text back
  4. They send POST http://localhost:4000/v1/messages with the same model and messages and get {"role":"assistant","content":[{"type":"text","text":"..."}]}
  5. The e2e run does steps 1 to 4 for every endpoint, provider, and credential mode, so the broken combination is the one red cell next to its green siblings

Relevant issues

Affected release

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*, make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

Shared setup: a live proxy on http://localhost:4000 with Postgres and STORE_MODEL_IN_DB=True, provider keys in the environment (OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, VERTEXAI_CREDENTIALS, VERTEXAI_PROJECT, AWS_BEARER_TOKEN_BEDROCK, TOGETHER_API_KEY). Master key, virtual keys, and provider keys are redacted below. The case walked by hand is the stored_credential cell family for Anthropic, which is the same shape every cell in the matrix takes: create the credential, register a deployment that names it, generate a virtual key, then call the endpoint as a customer would. The whole run below was captured on video at the tip and posted in Slack: https://berriaillm.slack.com/archives/D0BE7TV8KSQ/p1790066286931849

Before (30d8b12)

The proxy answers, but nothing asserts it across endpoints, providers, and auth modes

  1. ls tests/e2e/llm_translation/ | grep -c endpoint_matrix (in a worktree at the merge base)
    0
    
  2. python -m pytest tests/e2e/llm_translation/test_endpoint_matrix_e2e.py -q
    ERROR: file or directory not found: tests/e2e/llm_translation/test_endpoint_matrix_e2e.py
    exit code: 4
    
  3. The same POST /credentials, POST /model/new, POST /key/generate, and the three inference calls listed under After behave identically at this commit, so a translation bug on one of /v1/messages, /v1/chat/completions, or /v1/responses for a stored credential would only be found by whichever endpoint-specific test happened to cover that exact provider and auth mode

After (43a7968)

Stored credential, Anthropic, three endpoints through the proxy

  1. curl -X POST http://localhost:4000/credentials -H "Authorization: Bearer $MASTER" -d '{"credential_name":"proof-anthropic-9716","credential_values":{"api_key":"<ANTHROPIC_API_KEY>"},"credential_info":{}}'
    {"success":true,"message":"Credential created successfully"}
    
  2. curl -X POST http://localhost:4000/model/new -H "Authorization: Bearer $MASTER" -d '{"model_name":"proof-claude-9716","litellm_params":{"model":"anthropic/claude-haiku-4-5","litellm_credential_name":"proof-anthropic-9716"}}'
    {"model_name": "proof-claude-9716", "model_id": "9487fd5b-8257-4cb6-b9fa-5cc411054bf4"}
    
  3. curl -X POST http://localhost:4000/key/generate -H "Authorization: Bearer $MASTER" -d '{"models":[]}' returns a fresh virtual key sk-...fCJg
  4. curl -X POST http://localhost:4000/v1/chat/completions -H "Authorization: Bearer <virtual key>" -d '{"model":"proof-claude-9716","messages":[{"role":"user","content":"Reply with one short friendly sentence."}],"max_tokens":64}'
    {"choices[0].message.content": "Hey there! \ud83d\udc4b How can I help you today?", "model": "proof-claude-9716"}
    
  5. curl -X POST http://localhost:4000/v1/messages -H "Authorization: Bearer <virtual key>" -d '{"model":"proof-claude-9716","messages":[{"role":"user","content":"Reply with one short friendly sentence."}],"max_tokens":64}'
    {"role": "assistant", "content[0].text": "Hey there! Hope you're having a great day! \ud83d\ude0a"}
    
  6. curl -X POST http://localhost:4000/v1/responses -H "Authorization: Bearer <virtual key>" -d '{"model":"proof-claude-9716","input":"Reply with one short friendly sentence."}'
    {"status": "completed", "output_text": "Hey there! \ud83d\ude0a"}
    

The matrix does the above for every cell, live

  1. uv run pytest tests/e2e/llm_translation/test_endpoint_matrix_e2e.py -m "not replayable" -q (Gemini, Vertex, Bedrock, Together: 75 cells, real providers)
    75 passed, 60 deselected in 135.87s (0:02:15)
    
  2. E2E_FIXTURE_MODE=record E2E_FIXTURE_DIR=$HOME/e2e-matrix-fixtures-tip uv run pytest tests/e2e/llm_translation/test_endpoint_matrix_e2e.py -m replayable -q (OpenAI, Anthropic: 60 cells, real providers through the edge)
    60 passed, 75 deselected in 232.40s (0:03:52)
    
  3. OPENAI_API_KEY=sk-bogus ANTHROPIC_API_KEY=sk-ant-bogus E2E_FIXTURE_MODE=replay E2E_FIXTURE_DIR=$HOME/e2e-matrix-fixtures-tip uv run pytest tests/e2e/llm_translation/test_endpoint_matrix_e2e.py -m replayable -q (bogus provider keys prove zero egress)
    60 passed, 75 deselected in 22.68s
    

Mutation: a deployment holding a wrong literal key turns exactly its cells red

  1. OPENAI_API_KEY=sk-bogus E2E_MATRIX_PROVIDERS=openai E2E_MATRIX_AUTH_MODES=inline uv run pytest tests/e2e/llm_translation/test_endpoint_matrix_e2e.py -k "chat_completions-nonstream or messages-nonstream or responses-nonstream" -q
    FAILED ...[chat_completions-nonstream-openai-inline] - openai.AuthenticationError: Error code: 401 ... Incorrect API key provided: sk-bogus
    FAILED ...[messages-nonstream-openai-inline] - anthropic.AuthenticationError: Error code: 401 ... Incorrect API key provided: sk-bogus
    FAILED ...[responses-nonstream-openai-inline] - openai.AuthenticationError: Error code: 401 ... Incorrect API key provided: sk-bogus
    3 failed, 11 deselected in 17.28s
    

Type

✅ Test

Caveats

Medium

  • Bedrock, Gemini, Vertex, and Together have no generic edge mount, so their 75 cells hit providers live in every fixture mode and cost real money on each run
  • Replay proves routing and response shape only: the edge keys fixtures on the request body, never on the provider auth header, so a replayed green cell says nothing about which credential the proxy sent; the live and record lanes are the credential check
  • The stored-credential and env-ref cells cannot distinguish "the proxy used the stored secret" from "the proxy fell back to the same env var"; the inline mutation above is the only lane that proves the deployment's own secret is used
  • The hosted Buildkite lane (litellm-e2e-pr build 686 on this tip) runs all 135 cells but its runner pod only holds ANTHROPIC_API_KEY and VERTEXAI_CREDENTIALS, so 78 inline and stored_credential cells fail by name (openai inline auth needs OPENAI_API_KEY in the test environment) while all 45 env_ref cells and all 12 Anthropic inline and stored_credential cells pass; the conversational matrix already on main errors the same way 90 times. BerriAI/project-releaser#262 hands the pod OPENAI_API_KEY, GEMINI_API_KEY, VERTEXAI_PROJECT and TOGETHER_API_KEY from the Secret the gateway already mounts. AWS_BEARER_TOKEN_BEDROCK is in no cluster Secret (the gateway uses IRSA), so the 14 Bedrock inline and stored_credential cells stay red there until that key is added to the stage litellm-provider-keys secret

Low

  • The edge now answers the proxy's scheduled GET /v1/models discovery with 599 instead of recording it; only the exact empty-query path is filtered, GET /v1/models?purpose=batch still records and replays
  • Build 686 also failed three tests outside this PR's diff (test_vertex_chat_vision_describes_image, test_rust_ocr_response[mistral] on a Mistral 429, test_vertex_prompt_caching_reads_cache) and errored the 90 conversational matrix cells on OPENAI_API_KEY; the main cadence rerun at litellm 25af172 (litellm-e2e-pr build 691) fails the same vision and OCR tests, so those are red on main independently of this branch
  • Rerank is not in the matrix; the existing rerank tests stay as they are
  • Three registry ids (llm.messages.openai.basic.{nonstream,stream}.works, llm.responses.anthropic.basic.stream.works) landed on main via test(e2e): add conversational matrix across chat, messages and responses #42359 while this PR was open, so the merge keeps main's rows and the matrix cells cover them through their covers markers rather than duplicate rows; collector.py --strict still exits 0 with zero orphans
  • /credentials management calls now go to the control plane in split deployments (CONTROL_PLANE_PREFIXES); a test that expected them on a gateway replica would have been getting 404s from the stage-mirror stack already

Live PR risk

Verdict: no breaking or backward incompatible change found. Every changed symbol lives in the tests/e2e harness and every dependent is another e2e test, so the A/B is the same harness run at the merge base and at the tip against the same live proxy and the same real providers

Breaking: none observed

Backward incompatible: none. deterministic_marker still returns the same value for every per-test call site; only markers drawn inside a module- or class-scoped fixture change owner, and no recorded bundle on main holds one of those (see Regression risk). ProviderEdge still records and replays every path except the exact empty-query GET /v1/models. ProxyClient.register_models is new and only the matrix calls it. CONTROL_PLANE_PREFIXES gains /credentials; the existing entries and the replica fan-out for inference routes are unchanged

Regression risk: a replayable test that drew a marker inside a module- or class-scoped fixture would get a different marker at head than the bundle recorded at base holds, and miss its fixture on the first replay after merge. The four modules on main that draw markers inside such fixtures (router/test_auto_router_regressions_e2e.py, access_control/test_model_access_group_e2e.py, quota_management/spend_tracking/test_key_attribution_e2e.py, quota_management/budgets/test_model_access_group_budget_e2e.py) carry no replayable marker and no edge mount, so their markers never enter a bundle; the scheduled recorder re-records the replayable lane from scratch anyway

Dependency graph, base 30d8b12 vs head 43a7968, same live proxy (port 4000, split control plane 4001 and replicas 4010/4011):

  • deterministic_marker / marker_owner (tests/e2e/fixture_mode.py): every replayable e2e test. Verified live: -m replayable record lane over tests/e2e at head, 174 passed, 1 failed, 4 skipped; the one failure is test_reliability_cache_e2e.py::test_exact_cache_returns_cached, which fails identically at base against this proxy (no x-litellm-cache-key on the second call, pre-existing). Replay of that bundle at head: 164 passed, 11 failed; the same 10 spend-log tests plus the cache test. The 10 spend-log failures reproduce at base: recording the same five spend tests from the base worktree into a fresh bundle and replaying them fails the same 10 nodes (10 failed, 12 passed), because a replayed request writes no fresh spend row for the replayed call id while the assertion reads the live database. Pre-existing, unrelated to this diff
  • ProviderEdge scheduled-discovery filter (tests/e2e/provider_edge.py): every edge-wired test. Verified live in the record and replay lanes above, plus the three new unit cases in tests/e2e/test_provider_edge.py
  • CONTROL_PLANE_PREFIXES /credentials (tests/e2e/transport.py): every stored-credential e2e test on the stage-mirror job. Verified live on the local split deployment (60 stored and inline cells above) and pinned by tests/e2e/test_proxy_client.py::test_split_deployment_reads_management_routes_back_from_the_control_plane; the hosted stage-mirror job on this tip is waiting for a LiteLLM Engineering approval of the e2e-changed environment, which I cannot grant
  • ProxyClient.register_models (tests/e2e/proxy_client.py): the matrix deployments fixture only. Verified live in every lane above
  • Coverage registry rows: tests/e2e/coverage_registry/collector.py --strict exits 0 with zero orphans at head

Not verified: the failure-mode leg (paused Postgres, concurrent bursts) and the packaging leg did not run; the diff moves no runtime pin and adds no production code path, so neither leg has a target. Bedrock inline and stored_credential cells were verified locally with AWS_BEARER_TOKEN_BEDROCK but cannot be verified on the hosted runner until that key exists there

QA runbook

  • tests/e2e/llm_translation/test_endpoint_matrix_e2e.py::TestEndpointMatrix::test_endpoint_answers_through_every_provider_and_auth_mode[---<auth_mode>] - one cell per endpoint x provider x auth mode; the proxy answers the endpoint with a real, non-empty result through a deployment whose secret is held the way <auth_mode> says. Needs STORE_MODEL_IN_DB=True and the provider variables named in endpoint_matrix.py (OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, VERTEXAI_CREDENTIALS plus VERTEXAI_PROJECT, AWS_BEARER_TOKEN_BEDROCK, TOGETHER_API_KEY); a missing variable fails only that provider's inline and stored_credential cells by name rather than skipping, while its os.environ/ cells and every other provider still run. E2E_MATRIX_PROVIDERS and E2E_MATRIX_AUTH_MODES narrow the run; an unknown name fails at collection

    • For stored_credential only: curl -X POST http://localhost:4000/credentials -H "Authorization: Bearer sk-1234" -d '{"credential_name":"cred-1","credential_values":{"api_key":"<provider key>"},"credential_info":{}}' and expect {"success":true,...}
    • curl -X POST http://localhost:4000/model/new -H "Authorization: Bearer sk-1234" -d '{"model_name":"m-1","litellm_params":{"model":"<backend from endpoint_matrix.py>", <"api_key":"os.environ/OPENAI_API_KEY"> or <"api_key":"<literal>"> or <"litellm_credential_name":"cred-1">, ...provider params}}' and expect a model_info.id
    • curl -X POST http://localhost:4000/key/generate -H "Authorization: Bearer sk-1234" -d '{"models":[]}' and use the returned key below
    • Call the cell's endpoint with "model":"m-1": /v1/chat/completions and /v1/completions expect non-empty choices[0] text; /v1/messages expects role: assistant and a non-empty text block; /v1/responses expects status: completed and non-empty output text; /v1/embeddings (with "encoding_format":"float") expects a vector longer than one element with a non-zero component; /v1/audio/speech expects non-empty audio bytes; /v1/audio/transcriptions expects non-empty text; /v1/images/generations and /v1/images/edits expect a data[0] with b64_json or url; /v1/moderations expects one results[0] with a categories object. For the stream cells, expect at least one content delta and a terminal event
    • Tear down: POST /model/delete with the id, then DELETE /credentials/cred-1; the fixture registers each delete the moment the resource exists, so a failure partway through setup still tears down what it made
    • Missing secret: unset OPENAI_API_KEY in the pytest process only and run E2E_MATRIX_PROVIDERS=openai,anthropic ... -k chat_completions-nonstream; expect exactly openai-inline and openai-stored_credential red with needs OPENAI_API_KEY, the other four green (2 failed, 4 passed)
    • Sanity check: this test makes sense to add and is not hand-wavey (e.g., assert actual expected spend instead of just spend > 0) or potentially flaky
  • tests/e2e/test_fixture_mode.py::TestDeterministicMarker::test_module_fixture_markers_belong_to_the_module_not_its_first_test - a marker drawn inside a module-scoped fixture is keyed by the module node, not by whichever cell pytest runs first, so a full recording replays a narrowed -k or E2E_MATRIX_* selection. Mutation: with marker_owner() reverted to current_test_key() the test fails, restored it passes (18 passed)

    • Record the replayable lane (-m replayable, 60 passed), then replay only -k embeddings-nonstream-openai-inline with OPENAI_API_KEY=sk-bogus; expect 1 passed with zero provider calls
    • Sanity check: this test makes sense to add and is not hand-wavey (e.g., assert actual expected spend instead of just spend > 0) or potentially flaky
  • tests/e2e/test_provider_edge.py (the three new cases) - the edge keys fixtures by query string, keeps GET /v1/models?purpose=batch as ordinary traffic, and neither records nor demands the proxy's scheduled empty-query GET /v1/models

    • Run a record session with an edge-wired OpenAI deployment and wait for the proxy's refresh_model_info job to fire; expect no get-openai-v1-models.json in the bundle
    • Replay the same bundle; expect no leftover-interaction failure at teardown
    • Sanity check: this test makes sense to add and is not hand-wavey (e.g., assert actual expected spend instead of just spend > 0) or potentially flaky
  • tests/e2e/test_proxy_client.py::TestSplitDeployment::test_split_deployment_reads_management_routes_back_from_the_control_plane - /credentials/<name> resolves to the control plane in a split deployment, like /key/info and /project/info, while /v1/models still fans out to the gateway replicas

    • Run any stored_credential matrix cell against a split deployment (LITELLM_CONTROL_PLANE_URL and LITELLM_PROXY_REPLICA_URLS set); expect the credential create and delete to return 200 instead of 404
    • Sanity check: this test makes sense to add and is not hand-wavey (e.g., assert actual expected spend instead of just spend > 0) or potentially flaky

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR
  • Ran /live-pr-risk at 43a7968: no breaking or backward incompatible change; see the Live PR risk section above

Note

Low Risk
Changes are confined to e2e tests, docs, and test harness helpers; no production proxy or gateway logic is modified.

Overview
Adds a parametrized e2e endpoint matrix (endpoint_matrix.py + test_endpoint_matrix_e2e.py) that exercises ten inference routes across six catalog providers and three credential shapes (env_ref, inline, stored), with registry covers ids and E2E_MATRIX_PROVIDERS / E2E_MATRIX_AUTH_MODES filters. OpenAI and Anthropic cells are edge-wired and @pytest.mark.replayable; deployments register once per module via new ProxyClient.register_models batch API.

Fixture/replay plumbing: deterministic_marker() keys off marker_owner() so module-scoped setup (matrix deployments) gets stable markers independent of which parametrized cell runs first; tests lock that in. The provider edge rejects the proxy’s scheduled empty-query GET /v1/models with 599 so record/replay neither captures nor owes that housekeeping traffic.

Harness routing: /credentials is treated as a control-plane path in split deployments; coverage YAML and CONTRIBUTING document the matrix and replay lane membership.

Reviewed by Cursor Bugbot for commit 43a7968. Bugbot is set up for automated code reviews on this repo. Configure here.

Link to Devin session: https://app.devin.ai/sessions/d756e8154a4149e3a6d779d13b2324e0
Open in Devin Desktop: https://app.devin.ai/desktop/session/d756e8154a4149e3a6d779d13b2324e0?variant=devin
Requested by: @mateo-berri

mateo-berri and others added 2 commits September 21, 2026 23:47
… and auth modes

One scenario per non-management inference endpoint, run over every catalog provider that serves it and every way the proxy can hold that provider's secret (os.environ reference, literal value, stored credential). Cells carry exact coverage registry ids and the OpenAI and Anthropic cells join the record/replay lane. The provider edge stops recording or owing the proxy's scheduled GET /v1/models discovery, and ProxyClient gains register_models so the matrix pays the propagation budget once per run instead of once per cell

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@greptile-apps

greptile-apps Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge; no outstanding blocking failure or repository-rule violation was identified.

Findings

  1. P1 Credential setup leaks resources ▶
  2. P2 Credentials escape cleanup ▶
  3. P2 Explanatory docstrings violate guidance ▶

Summary

This PR adds a parametrized E2E matrix covering inference endpoints across providers and credential modes, along with deterministic fixture support, provider-edge handling, batched model registration, coverage-registry entries, and test-harness documentation.

  • Exercises endpoint, provider, streaming, and authentication combinations through the proxy.
  • Adds record/replay support for OpenAI and Anthropic matrix cells.
  • Registers and tears down credentials and deployments safely during partial setup failures.
  • Routes credential-management requests through the E2E split transport’s control plane.
  • Documents the distinction between replayed routing/shape validation and live credential validation.

Reviews (3) · Last reviewed commit: "test(e2e): route /credentials to the con..."

Comment thread tests/e2e/llm_translation/test_endpoint_matrix_e2e.py
Comment on lines +332 to +336
for route, name in credentials.items():
proxy.create_credential(
CredentialCreateBody(credential_name=name, credential_values=dict(credential_values(providers[route])))
)
try:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Credentials escape cleanup

If a later credential creation fails, earlier credentials bypass cleanup and leave stale rows that can break deterministic replay reruns.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 09f01a8 with the same ExitStack change: cleanup is registered per resource as soon as it exists, not after the loop

Comment on lines +1 to +11
"""Provider catalog behind test_endpoint_matrix_e2e.py.

One `Provider` row per route the matrix drives. Adding a provider is adding a row
here (its credential fields, its backend model per endpoint family, and the edge
mount when the provider edge can record and replay it) plus the registry cells
those combinations claim. The test module never names a provider.

`E2E_MATRIX_PROVIDERS` and `E2E_MATRIX_AUTH_MODES` narrow the default of every
catalog row and every auth mode; an unknown name fails collection instead of
quietly selecting nothing.
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Explanatory docstrings violate guidance

These docstrings, including similar ones in the matrix test, violate the repository directive limiting comments to complex logic, tool directives, or TODOs. This requirement must be satisfied before merging.

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in eb35a07 and 09f01a8: explanatory docstrings dropped; only one-line module docstrings remain, matching the neighboring e2e modules

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread tests/e2e/llm_translation/test_endpoint_matrix_e2e.py
_deployment_body(key, providers[key[0]], credentials[key[0]] if key[2] == "stored_credential" else None)
for key in keys
)
model_ids: Final = proxy.register_models(bodies)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing secret fails every matrix cell

Medium Severity

credential_values() raises from the shared deployments fixture as soon as any selected provider is missing an env var. Because every cell depends on that fixture, env_ref cells and unrelated providers error at setup too, instead of only the inline and stored-credential cells for the provider whose secret is absent.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e4d9c22. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 09f01a8: markers allocated inside module-scoped fixtures now key off the module node, so a full recording replays a narrowed -k or E2E_MATRIX_* run

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction: 09f01a8 makes a missing secret fail only that provider's inline and stored_credential cells by name; env_ref cells and other providers still register

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment on lines +332 to +336
for route, name in credentials.items():
proxy.create_credential(
CredentialCreateBody(credential_name=name, credential_values=dict(credential_values(providers[route])))
)
try:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Credential setup leaks resources

When multiple stored-credential providers are selected, credentials are created before the cleanup try begins. If a later provider is missing a required environment variable or its /credentials request fails, setup raises and leaves the credentials created for earlier providers in the shared proxy database. Those stale credentials can contaminate later e2e runs. Start the protected scope before the loop or register cleanup immediately after each successful creation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 09f01a8: each credential and model registers its delete on an ExitStack the moment it is created, so partial setup tears down

Comment thread tests/e2e/llm_translation/test_endpoint_matrix_e2e.py
@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…ule fixture markers

Register credential and model cleanup as each one succeeds, so a failure
partway through deployments setup leaves nothing behind. A provider whose
secret is absent now fails only its inline and stored_credential cells by
variable name; its os.environ/ cells and every other provider still run.
Module-scoped fixtures allocate deterministic markers against the module
node, not whichever cell pytest happens to run first, so a full recording
replays a narrowed -k or E2E_MATRIX_* selection

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

…rovider credentials

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@mateo-berri

Copy link
Copy Markdown
Contributor

@greptileai

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@mateo-berri

Copy link
Copy Markdown
Contributor

bugbot run

@mateo-berri

Copy link
Copy Markdown
Contributor

@greptileai

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 43a7968. Configure here.

This branch is waiting to be deployed

1 waiting deployment
e2e-changed — 43a7968c Waiting Sep 22, 2026 by devin-ai-integration[bot] via Run changed e2e tests against the stage-mirror stack #9328
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant