Skip to content

test(e2e): rename Gateway to ProxyClient and expose it as a session-scoped pytest fixture - #33750

Merged
yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
litellm_lit4549_e2e_proxy_client
Jul 18, 2026
Merged

test(e2e): rename Gateway to ProxyClient and expose it as a session-scoped pytest fixture#33750
yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
litellm_lit4549_e2e_proxy_client

Conversation

@yassin-berriai

@yassin-berriai yassin-berriai commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

Linear ticket

Resolves LIT-4549

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • 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)

Type

🧹 Refactoring
✅ Test

Changes

Two changes to the e2e harness; no product code is touched.

Rename the misnamed shared proxy wrapper. tests/e2e/e2e_gateway.py held Gateway, which is not a gateway server; it is the client every suite uses to talk to the proxy (keys, models, chat/embed/ocr, spend read-backs, poll helpers). The file is now proxy_client.py and the class is ProxyClient, with build_gateway becoming build_proxy_client and the GatewayProvider protocol becoming ProxyClientProvider. The .gateway attribute suites held is now .proxy. Only identifiers changed; the git rename is recorded as a rename so history is preserved. Prose and string literals that use the word gateway for the proxy-server concept were left alone, and the docstrings/comments plus the e2e CLAUDE.md / CONTRIBUTING.md code examples were updated to match.

Make it a pytest fixture. Previously each suite built its own instance through a per-suite build_client() that called build_gateway() inside, so the proxy wiring was duplicated across every suite. There is now one session-scoped proxy fixture in tests/e2e/conftest.py:

@pytest.fixture(scope="session")
def proxy() -> ProxyClient:
    return build_proxy_client()

Each suite's client fixture depends on it and injects it, and each suite factory takes the client instead of constructing its own:

# before
def build_client() -> PassthroughClient:
    return PassthroughClient(gateway=build_gateway())

@pytest.fixture(scope="session")
def client() -> PassthroughClient:
    return build_client()

# after
def build_client(proxy: ProxyClient) -> PassthroughClient:
    return PassthroughClient(proxy=proxy)

@pytest.fixture(scope="session")
def client(proxy: ProxyClient) -> PassthroughClient:
    return build_client(proxy)

Behavior is unchanged: shared transport, data-plane/control-plane split routing, poll budget, typed request/response models, and resource cleanup all go through the same object. claude_code/ keeps calling build_proxy_client(...) directly with its own base URLs since it has its own harness and does not use the shared fixtures.

Screenshots / Proof of Fix

This is a rename plus fixture-wiring refactor of the test harness, so there is no product behavior to demonstrate with an LLM call; what has to hold is that the harness still imports, collects, type-checks, and resolves its coverage markers exactly as before. Captured at commit 37b8aac260

ruff check tests/e2e

All checks passed!

make lint-e2e-basedpyright (the CI gate; zero errors allowed)

uv run --no-sync basedpyright tests/e2e
0 errors, 0 warnings, 0 notes

pytest tests/e2e --collect-only (every suite's client fixture resolves against the new session-scoped proxy fixture; no import or fixture error)

272 tests collected in 0.21s

python -m coverage_registry.collector (every covers(...) marker still resolves after the rename; nothing regressed)

ALL                                153/385       39.7%
Headline coverage: 153/385  (39.7%)

QA runbook

No e2e test's assertions changed; this PR renames the shared harness object and moves its construction into a single session-scoped fixture, so there are no new per-test manual steps to reproduce. The behavior-preservation checks a reviewer can rerun are the four above: ruff check tests/e2e, make lint-e2e-basedpyright, pytest tests/e2e --collect-only, and python -m coverage_registry.collector from tests/e2e

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

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR renames the shared e2e harness object (GatewayProxyClient, e2e_gateway.pyproxy_client.py, .gateway.proxy, build_gatewaybuild_proxy_client, GatewayProviderProxyClientProvider) and promotes the proxy construction into a single session-scoped proxy pytest fixture in tests/e2e/conftest.py. No production code is touched.

  • Every suite's conftest.py now receives the proxy: ProxyClient fixture and injects it into build_client(proxy), eliminating the per-suite duplication of proxy construction.
  • The variable-shadowing issue flagged in the previous review (proxy naming both a ProxyConfig and a ProxyClient in claude_code/conftest.py) is resolved: the ProxyConfig object is now stored in proxy_config, and only the ProxyClient uses proxy.
  • Documentation (CLAUDE.md, CONTRIBUTING.md) and the error message in models.py are updated to match the new names.

Confidence Score: 5/5

Safe to merge — purely a rename refactor of test infrastructure with no production code touched.

The change is a mechanical, exhaustive rename across 56 test-only files. No logic changes occur anywhere: the same SplitTransport, poll budget, and resource-cleanup paths are wired together identically, just through the injected proxy fixture rather than per-suite construction. The previous variable-shadowing concern in claude_code/conftest.py is resolved (proxy_config now holds the ProxyConfig, proxy holds the ProxyClient). A grep confirms no stale e2e_gateway/build_gateway/.gateway references remain in the tree.

No files require special attention.

Important Files Changed

Filename Overview
tests/e2e/proxy_client.py Renamed from e2e_gateway.py; class renamed Gateway → ProxyClient, build_gateway → build_proxy_client. No logic changes.
tests/e2e/conftest.py Adds the new session-scoped proxy fixture and updates the resources fixture to use ProxyClientProvider / .proxy.
tests/e2e/claude_code/conftest.py Resolves previous variable-shadowing: ProxyConfig now stored in proxy_config, ProxyClient in proxy. Helper renamed _build_control_gateway → _build_control_plane_client.
tests/e2e/lifecycle.py GatewayProvider protocol renamed to ProxyClientProvider; .gateway property renamed to .proxy. No behavioral change.
tests/e2e/router/conftest.py All Gateway references updated to ProxyClient; client fixture now injects the session-scoped proxy.
tests/e2e/quota_management/budgets/budget_client.py Mechanical rename of .gateway → .proxy throughout; build_client now accepts ProxyClient instead of constructing its own.
tests/e2e/logging/logging_client.py All gateway references updated to proxy; build_logging_client now takes a ProxyClient argument.
tests/e2e/management/management_client.py Mechanical rename; build_client now accepts ProxyClient instead of calling build_gateway internally.
tests/e2e/mcp/mcp_client.py New suite (added during staging) fully updated to use ProxyClient/.proxy pattern matching the rest of the harness.

Reviews (3): Last reviewed commit: "test(e2e): rename Gateway to ProxyClient..." | Re-trigger Greptile

@yassin-berriai
yassin-berriai force-pushed the litellm_lit4549_e2e_proxy_client branch from fb57ccc to 37b8aac Compare July 17, 2026 18:46
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai please review the current head 37b8aac

Addressed the P2 shadowing finding in tests/e2e/claude_code/conftest.py. The local that held the built control-plane client was renamed gateway -> proxy by the mechanical pass, which collided with the ProxyConfig from resolve_proxy() and made proxy change type mid-function. The config is now proxy_config: ProxyConfig and proxy is exclusively the ProxyClient, so no variable changes type. The helper that builds it is renamed _build_control_gateway -> _build_control_plane_client since it returns a ProxyClient, not a gateway, which is the same misnomer this PR exists to remove

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_lit4549_e2e_proxy_client (c81c4a3) with litellm_internal_staging (010b200)1

Open in CodSpeed

Footnotes

  1. No successful run was found on litellm_internal_staging (6f4f4f6) during the generation of this report, so 010b200 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

…coped fixture

The shared proxy wrapper in tests/e2e/e2e_gateway.py was misnamed: Gateway is
not a gateway server, it is the client every suite uses to talk to the proxy
(keys, models, chat/embed/ocr, spend read-backs, poll helpers). Rename the
module to proxy_client.py and the class to ProxyClient, with build_gateway
becoming build_proxy_client and the GatewayProvider protocol becoming
ProxyClientProvider. The .gateway attribute suites held is now .proxy. Only
identifiers changed; prose and string literals that use the word gateway for the
proxy-server concept were left alone.

Each suite previously built its own instance through a per-suite build_client()
that called build_gateway() inside, duplicating the proxy wiring across suites.
There is now one session-scoped proxy fixture in tests/e2e/conftest.py; every
suite's client fixture depends on it and injects it, so the wiring lives in one
place. claude_code keeps building its own client directly since it has its own
harness and does not use the shared fixtures.

Behavior is unchanged: shared transport, data-plane/control-plane split routing,
poll budget, typed request/response models, and resource cleanup all go through
the same object.
@yassin-berriai
yassin-berriai force-pushed the litellm_lit4549_e2e_proxy_client branch from 8c07d6f to c81c4a3 Compare July 18, 2026 18:31
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai please review the current head c81c4a3

Rebased onto current litellm_internal_staging to resolve the merge conflict; squashed to a single commit. The rebase surfaced new e2e suites that landed on staging while this PR was open (the mcp suite, a team-member budget isolation test, and new budget_client readback methods) that still referenced the old Gateway/build_gateway/.gateway API; the mechanical rename plus the session-scoped proxy fixture injection were extended to them so they match the rest of the harness. Behavior is unchanged. Locally: ruff check tests/e2e clean, basedpyright tests/e2e 0 errors, pytest tests/e2e --collect-only 280 tests collected with no import or fixture error, and the coverage-registry collector resolves every covers(...) marker.

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.

3 participants