litellm/tests/e2e
Yassin Kortam 2fd7929dc3 test(e2e): cover tool-permission, tool-policy and llm-as-a-judge guardrails
Adds live coverage for three guardrails litellm implements itself, each driven
against a real chat completion and asserting on the permitted/denied tool or the
judge's verdict rather than a bare status code.

tool_permission is registered allow-list style (one allow rule,
default_action=deny, on_disallowed_action=block): an unlisted tool is rejected
pre-call with the denied tool named, and the listed tool survives the guardrail
and is called by the model. tool_policy is exercised through a key-scoped
blocked-tool override set with POST /v1/tool/policy: the blocked tool is
rejected pre-call while a sibling tool on the same key and the same guardrail
still reaches the model, so the block is attributable to the policy rather than
to the guardrail refusing all tool use. llm_as_a_judge scores the model's answer
against a French-only criterion; an English answer is rejected with 422 and the
failing verdict, and a French one comes back to the caller.

The judge test does not stop at the response. That guardrail fails open on any
internal error, and a fail-open returns an ordinary 200 that is identical to an
approval: same status, same body, and the applied-guardrails header still names
it. So both halves also read the guardrail's own run log at
/guardrails/usage/logs, where an approval is recorded as `passed`, an
intervention as `blocked`, and a fail-open as `flagged`. Without that leg the
accept half would pass just as happily against a build where adjudication never
ran.

Also corrects the llm_as_a_judge registry row. It asked for a pre_call block,
which the guardrail cannot do: it supports post_call only and the proxy rejects
registering it at pre_call outright, so the row could never go green as written.
Retargeted to post_call, which is what the guardrail actually enforces.

The judge runs on openai/gpt-4.1 rather than the suite's usual gpt-5.5 because
the guardrail hardcodes temperature=0 on its judge call, gpt-5.5 accepts only
the default temperature, and the resulting error is swallowed into a fail-open,
so gpt-5.5 can never adjudicate anything.

Covers guardrail.tool_permission.pre_call.blocks,
guardrail.tool_permission.pre_call.allows, guardrail.tool_policy.pre_call.blocks
and guardrail.llm_as_a_judge.post_call.blocks.

The guardrail params, the tool-policy override bodies and the chat helper live
in a suite-local module so the shared harness is untouched.
2026-07-27 15:54:40 -07:00
..
a2a fix(e2e): stop tests from breaking the shared proxy for every suite after them (#34664) 2026-07-25 23:12:55 +00:00
access_control test(true_rabbit): cover passthrough headers, batch assume-role, gemini, vllm, bedrock guardrails, batch rate-limit mapping (#33843) 2026-07-20 16:15:55 -07:00
batches fix(e2e): stop tests from breaking the shared proxy for every suite after them (#34664) 2026-07-25 23:12:55 +00:00
claude_code refactor(e2e): fold claude_code HTTP probes onto shared Gateway methods (#33760) 2026-07-18 19:03:01 +00:00
coverage_registry test(e2e): cover tool-permission, tool-policy and llm-as-a-judge guardrails 2026-07-27 15:54:40 -07:00
guardrails test(e2e): cover tool-permission, tool-policy and llm-as-a-judge guardrails 2026-07-27 15:54:40 -07:00
llm_translation fix(e2e): stop tests from breaking the shared proxy for every suite after them (#34664) 2026-07-25 23:12:55 +00:00
load test(e2e): move Admin UI Playwright suite to tests/e2e/ui (#34196) 2026-07-22 19:43:10 +00:00
logging test(e2e): add Other suite and Guardrails coverage incl. an MCP tool-call guardrail (#34149) 2026-07-21 14:06:29 -07:00
management fix(e2e): stop tests from breaking the shared proxy for every suite after them (#34664) 2026-07-25 23:12:55 +00:00
mcp test(e2e): cover MCP access-group tool selection at key creation (#34480) 2026-07-24 16:18:40 -07:00
other test(e2e): add Other suite and Guardrails coverage incl. an MCP tool-call guardrail (#34149) 2026-07-21 14:06:29 -07:00
quota_management refactor(e2e): drop require_env, read os.environ where a cred is used (#34413) 2026-07-23 19:14:22 +00:00
router test(e2e): add reliability suite covering fallback, timeout, and cache behavior (#34023) 2026-07-20 23:06:46 +00:00
ui fix(e2e/ui): resolve dashboard base URL from env instead of hardcoding localhost (#34739) 2026-07-27 10:19:32 -07:00
CLAUDE.md test(e2e): drive a real Linear OAuth MCP through chat completions under both ingress headers 2026-07-22 23:29:10 -07:00
conftest.py test(e2e): cover key max_budget blocks on personal, team, and team-member keys (#33895) 2026-07-22 17:48:18 -07:00
CONTRIBUTING.md chore(e2e): remove tests/e2e/docker-compose.yml (#33837) 2026-07-18 12:50:23 -07:00
e2e_config.py fix(e2e): stop tests from breaking the shared proxy for every suite after them (#34664) 2026-07-25 23:12:55 +00:00
e2e_db.py test(e2e): guard destructive spend-log truncate behind an explicit opt-in (#33751) 2026-07-20 08:47:39 -07:00
e2e_http.py test(e2e): cover /v1/images/edits (#34476) 2026-07-25 10:38:07 -07:00
junit_properties.py refactor(e2e): replace bespoke result reporter with standard JUnit report (#33758) 2026-07-17 20:53:22 +00:00
lifecycle.py test(e2e): cover key max_budget blocks on personal, team, and team-member keys (#33895) 2026-07-22 17:48:18 -07:00
models.py test(e2e): cover MCP access-group tool selection at key creation (#34480) 2026-07-24 16:18:40 -07:00
otel_client.py test(e2e): add Other suite and Guardrails coverage incl. an MCP tool-call guardrail (#34149) 2026-07-21 14:06:29 -07:00
proxy_client.py test(e2e): cover model update persisting to /model/info (#34017) 2026-07-20 21:13:54 +00:00
pytest.ini test(e2e): add weekly session-anomaly load test against real providers 2026-07-21 14:54:02 -07:00
transport.py test(e2e): cover /v1/images/edits (#34476) 2026-07-25 10:38:07 -07:00