feat(music-lab): POST /pipeline/{id}/retry — 실패 step 수동 재개

terminal failed 파이프라인을 마지막 실패 step부터 재개.
publish + youtube_video_id 있으면 중복 업로드 방지 409.
pytest.ini에 pythonpath=.. 추가 (PYTHONPATH=.. 없이 TestClient 테스트 구동).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-12 00:23:24 +09:00
parent e90e25d78f
commit 44dbe7c426
3 changed files with 61 additions and 1 deletions

View File

@@ -1,4 +1,5 @@
import pytest
from fastapi.testclient import TestClient
from app import db
from app.pipeline import orchestrator
@@ -81,3 +82,43 @@ async def test_publish_not_retried(fresh_db, monkeypatch):
await orchestrator.run_step(pid, "publish")
assert calls["n"] == 1
assert db.get_pipeline(pid)["state"] == "failed"
# ── Task 3: retry endpoint tests ─────────────────────────────────────────────
@pytest.fixture
def client(fresh_db):
from app.main import app
return TestClient(app)
def test_retry_failed_pipeline_retriggers(fresh_db, client, monkeypatch):
pid = db.create_pipeline(track_id=1)
job = db.create_pipeline_job(pid, "video")
db.update_pipeline_job(job, status="failed", error="boom")
db.update_pipeline_state(pid, "failed", failed_reason="video: boom")
called = {}
async def fake_run(p, step, *a):
called["pid"], called["step"] = p, step
monkeypatch.setattr(orchestrator, "run_step", fake_run)
r = client.post(f"/api/music/pipeline/{pid}/retry")
assert r.status_code in (200, 202)
assert r.json()["retrying_step"] == "video"
def test_retry_non_failed_409(fresh_db, client):
pid = db.create_pipeline(track_id=1) # state='created'
r = client.post(f"/api/music/pipeline/{pid}/retry")
assert r.status_code == 409
def test_retry_publish_with_video_id_rejected(fresh_db, client):
pid = db.create_pipeline(track_id=1)
job = db.create_pipeline_job(pid, "publish")
db.update_pipeline_job(job, status="failed", error="x")
db.update_pipeline_state(pid, "failed", failed_reason="publish: x",
youtube_video_id="abc123")
r = client.post(f"/api/music/pipeline/{pid}/retry")
assert r.status_code == 409