mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
test(e2e): use CI-served models and tighten project all-team-models denial check
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
56b1fcabd8
commit
b76730b77f
2 changed files with 20 additions and 7 deletions
|
|
@ -3,9 +3,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import warnings
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from pydantic import BaseModel, RootModel, ValidationError
|
||||
|
||||
from proxy_client import ProxyClient
|
||||
from e2e_http import NoBody, StreamingResponse, is_ok, unwrap
|
||||
|
|
@ -32,6 +33,7 @@ TEAM_MODEL_ACCESS_DENIED_MARKER = "team_model_access_denied"
|
|||
PROJECT_MODEL_ACCESS_DENIED_MARKER = "project_model_access_denied"
|
||||
ROUTE_NOT_ALLOWED_MARKER = "not allowed to call this route"
|
||||
ALL_TEAM_MODELS = "all-team-models"
|
||||
ALL_PROXY_MODELS = "all-proxy-models"
|
||||
|
||||
|
||||
class ApiErrorDetail(BaseModel):
|
||||
|
|
@ -121,12 +123,14 @@ class AccessControlClient:
|
|||
).project_id
|
||||
|
||||
def delete_project(self, project_id: str) -> None:
|
||||
_ = self.proxy.transport.delete(
|
||||
result = self.proxy.transport.delete(
|
||||
"/project/delete",
|
||||
headers=self.proxy.transport.master,
|
||||
json=ProjectDeleteBody(project_ids=[project_id]),
|
||||
response_type=NoBody,
|
||||
response_type=RootModel[list[ProjectIdentity]],
|
||||
)
|
||||
if not is_ok(result):
|
||||
warnings.warn(f"delete_project({project_id!r}) failed: {result}", stacklevel=2)
|
||||
|
||||
def project_key(self, team_id: str, project_id: str, models: list[str]) -> str:
|
||||
return self.proxy.generate_key(KeyGenerateBody(team_id=team_id, project_id=project_id, models=models))
|
||||
|
|
|
|||
|
|
@ -12,8 +12,10 @@ from __future__ import annotations
|
|||
|
||||
import pytest
|
||||
from access_control_client import (
|
||||
ALL_PROXY_MODELS,
|
||||
ALL_TEAM_MODELS,
|
||||
PROJECT_MODEL_ACCESS_DENIED_MARKER,
|
||||
TEAM_MODEL_ACCESS_DENIED_MARKER,
|
||||
AccessControlClient,
|
||||
)
|
||||
from e2e_config import unique_marker
|
||||
|
|
@ -22,9 +24,8 @@ from models import ChatResponse
|
|||
|
||||
pytestmark = pytest.mark.e2e
|
||||
|
||||
TEAM_MODEL = "gpt-5.6-sol"
|
||||
OUTSIDE_MODEL = "gpt-5.6-sol-eu"
|
||||
ALL_PROXY_MODELS = "all-proxy-models"
|
||||
TEAM_MODEL = "gemini-2.5-flash"
|
||||
OUTSIDE_MODEL = "gpt-5.5"
|
||||
|
||||
|
||||
def _chat_assert_completion(client: AccessControlClient, key: str, model: str) -> None:
|
||||
|
|
@ -67,10 +68,18 @@ class TestProjectAllTeamModels:
|
|||
|
||||
client.set_team_models(team_id, f"e2e-proj-team-{marker}", [TEAM_MODEL])
|
||||
|
||||
_chat_assert_completion(client, key, TEAM_MODEL)
|
||||
|
||||
denied = client.chat_status(key, OUTSIDE_MODEL, f"capital of France? {unique_marker()}")
|
||||
assert denied.status_code == 403 and "_model_access_denied" in denied.body, (
|
||||
assert denied.status_code == 403, (
|
||||
f"model outside the team's list must be denied 403, got {denied.status_code}: {denied.body[:300]}"
|
||||
)
|
||||
assert PROJECT_MODEL_ACCESS_DENIED_MARKER not in denied.body, (
|
||||
f"the denial must come from the key or team check, not the project check: {denied.body[:300]}"
|
||||
)
|
||||
assert TEAM_MODEL_ACCESS_DENIED_MARKER in denied.body, (
|
||||
f"403 body must be a team model-access denial, got: {denied.body[:300]}"
|
||||
)
|
||||
|
||||
def test_project_explicit_model_list_calls_model(
|
||||
self, client: AccessControlClient, resources: ResourceManager
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue