113 lines
3.6 KiB
Python
113 lines
3.6 KiB
Python
|
|
"""T050: Integration tests for finetune router endpoints."""
|
||
|
|
import pytest
|
||
|
|
from unittest.mock import MagicMock, patch
|
||
|
|
|
||
|
|
from app.core.exceptions import LLMCallError
|
||
|
|
from app.models.finetune_models import FinetuneStartResponse, FinetuneStatusResponse
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
# POST /api/v1/finetune/start
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
def test_finetune_start_returns_200_with_job_id(client):
|
||
|
|
start_resp = FinetuneStartResponse(job_id="glm-ft-router-test")
|
||
|
|
|
||
|
|
with patch("app.routers.finetune.finetune_service.submit_finetune") as mock_submit:
|
||
|
|
mock_submit.return_value = start_resp
|
||
|
|
|
||
|
|
resp = client.post(
|
||
|
|
"/api/v1/finetune/start",
|
||
|
|
json={
|
||
|
|
"jsonl_url": "s3://bucket/train.jsonl",
|
||
|
|
"base_model": "glm-4",
|
||
|
|
"hyperparams": {"n_epochs": 3},
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
assert resp.status_code == 200
|
||
|
|
data = resp.json()
|
||
|
|
assert data["job_id"] == "glm-ft-router-test"
|
||
|
|
|
||
|
|
|
||
|
|
def test_finetune_start_without_hyperparams(client):
|
||
|
|
start_resp = FinetuneStartResponse(job_id="glm-ft-nohp")
|
||
|
|
|
||
|
|
with patch("app.routers.finetune.finetune_service.submit_finetune") as mock_submit:
|
||
|
|
mock_submit.return_value = start_resp
|
||
|
|
|
||
|
|
resp = client.post(
|
||
|
|
"/api/v1/finetune/start",
|
||
|
|
json={
|
||
|
|
"jsonl_url": "s3://bucket/train.jsonl",
|
||
|
|
"base_model": "glm-4",
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
assert resp.status_code == 200
|
||
|
|
assert resp.json()["job_id"] == "glm-ft-nohp"
|
||
|
|
|
||
|
|
|
||
|
|
def test_finetune_start_llm_call_error_returns_503(client):
|
||
|
|
with patch("app.routers.finetune.finetune_service.submit_finetune") as mock_submit:
|
||
|
|
mock_submit.side_effect = LLMCallError("SDK failed")
|
||
|
|
|
||
|
|
resp = client.post(
|
||
|
|
"/api/v1/finetune/start",
|
||
|
|
json={
|
||
|
|
"jsonl_url": "s3://bucket/train.jsonl",
|
||
|
|
"base_model": "glm-4",
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
assert resp.status_code == 503
|
||
|
|
assert resp.json()["code"] == "LLM_CALL_ERROR"
|
||
|
|
|
||
|
|
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
# GET /api/v1/finetune/status/{job_id}
|
||
|
|
# ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
def test_finetune_status_returns_200_with_fields(client):
|
||
|
|
status_resp = FinetuneStatusResponse(
|
||
|
|
job_id="glm-ft-router-test",
|
||
|
|
status="RUNNING",
|
||
|
|
progress=30,
|
||
|
|
)
|
||
|
|
|
||
|
|
with patch("app.routers.finetune.finetune_service.get_finetune_status") as mock_status:
|
||
|
|
mock_status.return_value = status_resp
|
||
|
|
|
||
|
|
resp = client.get("/api/v1/finetune/status/glm-ft-router-test")
|
||
|
|
|
||
|
|
assert resp.status_code == 200
|
||
|
|
data = resp.json()
|
||
|
|
assert data["job_id"] == "glm-ft-router-test"
|
||
|
|
assert data["status"] == "RUNNING"
|
||
|
|
assert data["progress"] == 30
|
||
|
|
|
||
|
|
|
||
|
|
def test_finetune_status_succeeded(client):
|
||
|
|
status_resp = FinetuneStatusResponse(
|
||
|
|
job_id="glm-ft-done",
|
||
|
|
status="SUCCESS",
|
||
|
|
)
|
||
|
|
|
||
|
|
with patch("app.routers.finetune.finetune_service.get_finetune_status") as mock_status:
|
||
|
|
mock_status.return_value = status_resp
|
||
|
|
|
||
|
|
resp = client.get("/api/v1/finetune/status/glm-ft-done")
|
||
|
|
|
||
|
|
assert resp.status_code == 200
|
||
|
|
assert resp.json()["status"] == "SUCCESS"
|
||
|
|
|
||
|
|
|
||
|
|
def test_finetune_status_llm_call_error_returns_503(client):
|
||
|
|
with patch("app.routers.finetune.finetune_service.get_finetune_status") as mock_status:
|
||
|
|
mock_status.side_effect = LLMCallError("SDK failed")
|
||
|
|
|
||
|
|
resp = client.get("/api/v1/finetune/status/glm-ft-bad")
|
||
|
|
|
||
|
|
assert resp.status_code == 503
|
||
|
|
assert resp.json()["code"] == "LLM_CALL_ERROR"
|