Spaces:
Running
Running
File size: 6,271 Bytes
88c0e85 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | """Router-level error path tests for OpenAI-compatible payloads."""
from __future__ import annotations
import asyncio
import pytest
from fastapi import HTTPException
from app.core.model_registry import ModelSpec
from app.routers import chat, completions, embeddings, responses
from app.schemas.chat import ChatCompletionRequest
from app.schemas.completions import CompletionRequest
from app.schemas.responses import ResponseRequest
def _raise_key_error(_: str) -> None:
raise KeyError("unknown")
def test_completions_unknown_model_returns_404_openai_error(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("app.routers.completions.get_model_spec", _raise_key_error)
payload = CompletionRequest.model_validate({"model": "missing", "prompt": "Hi"})
with pytest.raises(HTTPException) as exc:
asyncio.run(completions.create_completion(payload))
assert exc.value.status_code == 404
assert exc.value.detail["type"] == "model_not_found"
assert exc.value.detail["param"] == "model"
assert exc.value.detail["code"] == "model_not_found"
def test_chat_unknown_model_returns_404_openai_error(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("app.routers.chat.get_model_spec", _raise_key_error)
payload = ChatCompletionRequest.model_validate(
{
"model": "missing",
"messages": [{"role": "user", "content": "Hi"}],
}
)
with pytest.raises(HTTPException) as exc:
asyncio.run(chat.create_chat_completion(payload))
assert exc.value.status_code == 404
assert exc.value.detail["type"] == "model_not_found"
assert exc.value.detail["param"] == "model"
assert exc.value.detail["code"] == "model_not_found"
def test_responses_unknown_model_returns_404_openai_error(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("app.routers.responses.get_model_spec", _raise_key_error)
payload = ResponseRequest.model_validate({"model": "missing", "input": "Hi"})
with pytest.raises(HTTPException) as exc:
asyncio.run(responses.create_response(payload))
assert exc.value.status_code == 404
assert exc.value.detail["type"] == "model_not_found"
assert exc.value.detail["param"] == "model"
assert exc.value.detail["code"] == "model_not_found"
def test_completions_generation_exception_returns_generation_error(
monkeypatch: pytest.MonkeyPatch,
) -> None:
def boom(*_: object, **__: object) -> None:
raise RuntimeError("boom")
monkeypatch.setattr("app.routers.completions.get_model_spec", lambda _: None)
monkeypatch.setattr("app.routers.completions.engine.generate", boom)
payload = CompletionRequest.model_validate({"model": "GPT3-dev", "prompt": "Hi"})
with pytest.raises(HTTPException) as exc:
asyncio.run(completions.create_completion(payload))
assert exc.value.status_code == 500
assert exc.value.detail["type"] == "server_error"
assert exc.value.detail["code"] == "generation_error"
assert "Generation error:" in exc.value.detail["message"]
def test_chat_generation_exception_returns_generation_error(
monkeypatch: pytest.MonkeyPatch,
) -> None:
def boom(*_: object, **__: object) -> None:
raise RuntimeError("boom")
monkeypatch.setattr(
"app.routers.chat.get_model_spec",
lambda model: ModelSpec(name=model, hf_repo="dummy/instruct", is_instruct=True),
)
monkeypatch.setattr("app.routers.chat.engine.apply_chat_template", lambda *_: "prompt")
monkeypatch.setattr("app.routers.chat.engine.generate", boom)
payload = ChatCompletionRequest.model_validate(
{
"model": "GPT4-dev-177M-1511-Instruct",
"messages": [{"role": "user", "content": "Hi"}],
}
)
with pytest.raises(HTTPException) as exc:
asyncio.run(chat.create_chat_completion(payload))
assert exc.value.status_code == 500
assert exc.value.detail["type"] == "server_error"
assert exc.value.detail["code"] == "generation_error"
assert "Generation error:" in exc.value.detail["message"]
def test_responses_generation_exception_returns_generation_error(
monkeypatch: pytest.MonkeyPatch,
) -> None:
def boom(*_: object, **__: object) -> None:
raise RuntimeError("boom")
monkeypatch.setattr(
"app.routers.responses.get_model_spec",
lambda model: ModelSpec(name=model, hf_repo="dummy/base", is_instruct=False),
)
monkeypatch.setattr("app.routers.responses.engine.generate", boom)
payload = ResponseRequest.model_validate({"model": "GPT3-dev", "input": "Hi"})
with pytest.raises(HTTPException) as exc:
asyncio.run(responses.create_response(payload))
assert exc.value.status_code == 500
assert exc.value.detail["type"] == "server_error"
assert exc.value.detail["code"] == "generation_error"
assert "Generation error:" in exc.value.detail["message"]
def test_responses_structured_input_with_non_instruct_model_returns_400(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr(
"app.routers.responses.get_model_spec",
lambda model: ModelSpec(name=model, hf_repo="dummy/base", is_instruct=False),
)
payload = ResponseRequest.model_validate(
{
"model": "GPT3-dev",
"input": [{"role": "user", "content": "Hi"}],
}
)
with pytest.raises(HTTPException) as exc:
asyncio.run(responses.create_response(payload))
assert exc.value.status_code == 400
assert exc.value.detail["type"] == "invalid_request_error"
assert exc.value.detail["param"] == "model"
assert "not an instruct model" in exc.value.detail["message"]
def test_embeddings_enabled_backend_returns_pending_code(
monkeypatch: pytest.MonkeyPatch,
) -> None:
class DummySettings:
enable_embeddings_backend = True
monkeypatch.setattr("app.routers.embeddings.get_settings", lambda: DummySettings())
with pytest.raises(HTTPException) as exc:
asyncio.run(embeddings.create_embeddings())
assert exc.value.status_code == 501
assert exc.value.detail["type"] == "not_implemented_error"
assert exc.value.detail["code"] == "embeddings_backend_pending"
|