sgl-router: experimental Rust HTTP router for SGLang worker pools (#25851)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
aae04b1241
commit
6e8fe176be
@@ -0,0 +1,64 @@
|
||||
"""
|
||||
Smoke tests for /v1/models and /v1/chat/completions (streaming + non-streaming).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
MODEL = "Qwen/Qwen3-0.6B"
|
||||
|
||||
|
||||
def test_models(router: str) -> None:
|
||||
"""GET /v1/models must list the configured model."""
|
||||
resp = httpx.get(f"{router}/v1/models", timeout=30)
|
||||
assert resp.status_code == 200, resp.text
|
||||
data = resp.json()
|
||||
ids = [m["id"] for m in data.get("data", [])]
|
||||
assert any(
|
||||
MODEL in mid for mid in ids
|
||||
), f"Model {MODEL!r} not found in /v1/models response: {ids}"
|
||||
|
||||
|
||||
def test_chat_non_streaming(router: str) -> None:
|
||||
"""POST /v1/chat/completions (stream=False) returns an assistant message."""
|
||||
payload = {
|
||||
"model": MODEL,
|
||||
"messages": [{"role": "user", "content": "Say hi."}],
|
||||
"max_tokens": 10,
|
||||
"stream": False,
|
||||
}
|
||||
resp = httpx.post(f"{router}/v1/chat/completions", json=payload, timeout=60)
|
||||
assert resp.status_code == 200, resp.text
|
||||
body = resp.json()
|
||||
choice = body["choices"][0]
|
||||
assert choice["message"]["role"] == "assistant"
|
||||
assert choice["message"]["content"], "Expected non-empty assistant content"
|
||||
|
||||
|
||||
def test_chat_streaming(router: str) -> None:
|
||||
"""POST /v1/chat/completions (stream=True) returns >=2 SSE chunks incl. [DONE]."""
|
||||
payload = {
|
||||
"model": MODEL,
|
||||
"messages": [{"role": "user", "content": "Say hi."}],
|
||||
"max_tokens": 10,
|
||||
"stream": True,
|
||||
}
|
||||
chunks: list[str] = []
|
||||
with httpx.stream(
|
||||
"POST",
|
||||
f"{router}/v1/chat/completions",
|
||||
json=payload,
|
||||
timeout=60,
|
||||
) as resp:
|
||||
assert resp.status_code == 200, resp.read().decode()
|
||||
for line in resp.iter_lines():
|
||||
line = line.strip()
|
||||
if line.startswith("data:"):
|
||||
chunks.append(line)
|
||||
|
||||
assert len(chunks) >= 2, f"Expected >=2 SSE chunks, got {len(chunks)}: {chunks}"
|
||||
assert any(
|
||||
"[DONE]" in c for c in chunks
|
||||
), f"No [DONE] chunk found in SSE stream: {chunks}"
|
||||
Reference in New Issue
Block a user