mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-12 03:48:56 +00:00
* test: move guardrails, image, audio, batches, search legacy tests to unit * test: restore the custom guardrail and remaining chunk 1 unit rows * test: move the ocr matrix to e2e * test: drop comments from moved tests and fix vertex ocr credentials * test: move litellm utils and unified google legacy tests to their tiers * test: move logging callback and pass-through unit legacy tests to their tiers Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test: move store_model_in_db legacy tests and start the admin ui migration Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test: finish the proxy job rows and drop their CircleCI jobs Moves the remaining multi-instance, openai endpoint, otel, pass-through and top-level proxy tests into tests/integration with scripted upstreams, rewrites the weak replacements to assert the outbound wire and exact responses, and removes the build_and_test job group this PR owns from CircleCI * test: tighten the key generation and error log assertions, rename migrated unit files to their mapped names * test: shard the pagerduty unit tests and record the rust harness file on the coverage allowlist * test: drive the SSO sign-in tests through a scripted IdP and isolate the cost center stand-in * test: type the e2e beta header, prompt cache and secret manager values * test: assert the missing model error message on the OpenAI routes * test: drop the deleted otel base class import and restore mcp redaction and exact langfuse usage checks * test: make the langfuse fixture directory a package for the layout check * test: restore collected no-match cases, real langfuse and gcs payload checks, and gate the aws secret lane * test: keep the ocr e2e pdf fixture next to the test * test: put meta below covers on the streaming tool search e2e * test: run the OCR matrix against a scripted upstream and fix two runner-only e2e failures * test: count only OCR calls in the OCR matrix recorder * test: pin OCR parse bodies and billed cost, group new e2e cases into classes * ci: restore the python image anchor dropped in the main sync --------- Co-authored-by: yuneng <yuneng@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
77 lines
3.3 KiB
Python
77 lines
3.3 KiB
Python
import json
|
|
import uuid
|
|
from typing import Final
|
|
|
|
from tests.integration._support.client import Gateway, object_value, string_value
|
|
from tests.integration._support.wire import Reply, Request, wire_server
|
|
|
|
|
|
def _delete_model_if_present(gateway: Gateway, identity: str) -> None:
|
|
if gateway.request("GET", "/model/info", params={"litellm_model_id": identity}).status_code == 200:
|
|
gateway.post("/model/delete", {"id": identity})
|
|
|
|
|
|
def test_model_deployment_can_be_used_and_deleted(gateway: Gateway) -> None:
|
|
model: Final = f"lifecycle-model-{uuid.uuid4().hex}"
|
|
identity: Final = f"lifecycle-model-id-{uuid.uuid4().hex}"
|
|
|
|
def upstream(request: Request) -> Reply:
|
|
body: Final = json.loads(request.body)
|
|
assert body["messages"] == [{"role": "user", "content": "model lifecycle"}]
|
|
return Reply(
|
|
body=json.dumps(
|
|
{
|
|
"id": "model-lifecycle-response",
|
|
"object": "chat.completion",
|
|
"created": 1,
|
|
"model": "gpt-4o-mini",
|
|
"choices": [
|
|
{
|
|
"index": 0,
|
|
"message": {"role": "assistant", "content": "available"},
|
|
"finish_reason": "stop",
|
|
}
|
|
],
|
|
"usage": {"prompt_tokens": 2, "completion_tokens": 1, "total_tokens": 3},
|
|
}
|
|
).encode(),
|
|
)
|
|
|
|
with gateway.scenario() as scenario:
|
|
with wire_server(upstream) as provider:
|
|
created: Final = gateway.post(
|
|
"/model/new",
|
|
{
|
|
"model_name": model,
|
|
"litellm_params": {
|
|
"model": "openai/gpt-4o-mini",
|
|
"api_base": f"{provider.url}/v1",
|
|
"api_key": "synthetic-model-key",
|
|
},
|
|
"model_info": {"id": identity},
|
|
},
|
|
)
|
|
assert string_value(object_value(created["model_info"])["id"]) == identity
|
|
scenario.cleanups.callback(_delete_model_if_present, gateway, identity)
|
|
|
|
response: Final = gateway.request(
|
|
"POST",
|
|
"/v1/chat/completions",
|
|
{"model": model, "messages": [{"role": "user", "content": "model lifecycle"}]},
|
|
)
|
|
assert response.status_code == 200, response.text
|
|
assert response.json()["choices"][0]["message"]["content"] == "available"
|
|
|
|
deleted: Final = gateway.request("POST", "/model/delete", {"id": identity})
|
|
assert deleted.status_code == 200, deleted.text
|
|
remaining: Final = gateway.request("GET", "/model/info", params={"litellm_model_id": identity})
|
|
assert remaining.status_code == 400, remaining.text
|
|
assert f"Model id = {identity} not found" in remaining.text
|
|
|
|
unavailable: Final = gateway.request(
|
|
"POST",
|
|
"/v1/chat/completions",
|
|
{"model": model, "messages": [{"role": "user", "content": "model lifecycle"}]},
|
|
)
|
|
assert unavailable.status_code == 400, unavailable.text
|
|
assert f"Invalid model name passed in model={model}" in unavailable.text
|