Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
94 lines
3.0 KiB
Python
94 lines
3.0 KiB
Python
"""/ingest 의 요약 트리거 규칙.
|
|
|
|
- 신규/변경 적재(loaded) → scheduled
|
|
- 소스 동일(skip)이라도 요약 미완료 unit 이 있으면 → resumed (재인덱싱 = 요약 재시도)
|
|
- 소스 동일 + 요약 전부 완료 → skip
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from config.settings import settings
|
|
from index.db import connect
|
|
from summarize.runner import PROMPT_VERSION
|
|
|
|
PAYLOAD = {
|
|
"MAIN_PROGRAM": "ZINGEST_T1",
|
|
"DESCRIPTION": "인제스트 테스트",
|
|
"INCLUDE_PROGRAM": [
|
|
{
|
|
"INCLUDE": "ZINGEST_T1",
|
|
"SOURCE_CODE": (
|
|
"REPORT zingest_t1.\n"
|
|
"START-OF-SELECTION.\n"
|
|
" PERFORM main.\n"
|
|
"FORM main.\n"
|
|
" SELECT * FROM t001 INTO TABLE gt_t001.\n"
|
|
"ENDFORM."
|
|
),
|
|
}
|
|
],
|
|
}
|
|
|
|
|
|
@pytest.fixture()
|
|
def client(tmp_path, monkeypatch):
|
|
import query.api as api
|
|
|
|
monkeypatch.setattr(settings, "database_url", f"sqlite:///{tmp_path / 'index.db'}")
|
|
monkeypatch.setattr(settings, "data_normalized", tmp_path / "normalized")
|
|
monkeypatch.setattr(settings, "data_parsed", tmp_path / "parsed")
|
|
monkeypatch.setattr(settings, "llm_base_url", "http://fake")
|
|
monkeypatch.setattr(settings, "llm_api_key", "fake-key")
|
|
|
|
calls: list[str] = []
|
|
|
|
def fake_summarize_bg(program: str) -> None: # 실제 LLM/위키는 건드리지 않는다
|
|
calls.append(program)
|
|
with api._summarizing_lock:
|
|
api._summarizing.discard(program)
|
|
|
|
monkeypatch.setattr(api, "_summarize_bg", fake_summarize_bg)
|
|
return TestClient(api.app), calls
|
|
|
|
|
|
def test_summarize_trigger_rules(client):
|
|
c, calls = client
|
|
|
|
# 1) 신규 적재 → scheduled
|
|
r = c.post("/ingest", json=PAYLOAD).json()
|
|
assert r["status"] == "loaded"
|
|
assert r["summarize"] == "scheduled"
|
|
assert r["pending_units"] > 0
|
|
assert calls == ["ZINGEST_T1"]
|
|
|
|
# 2) 같은 소스 재인덱싱 — 요약은 아직 미완료(가짜 bg) → resumed
|
|
r = c.post("/ingest", json=PAYLOAD).json()
|
|
assert r["status"] == "skip"
|
|
assert r["summarize"] == "resumed"
|
|
assert calls == ["ZINGEST_T1", "ZINGEST_T1"]
|
|
|
|
# 3) 요약 전부 완료 처리 후 재인덱싱 → skip (요약 재실행 없음)
|
|
con = connect()
|
|
try:
|
|
con.execute(
|
|
"UPDATE unit SET summary_status='done', summary_json='{}', prompt_version=? "
|
|
"WHERE program='ZINGEST_T1'", (PROMPT_VERSION,))
|
|
con.commit()
|
|
finally:
|
|
con.close()
|
|
r = c.post("/ingest", json=PAYLOAD).json()
|
|
assert r["status"] == "skip"
|
|
assert r["summarize"] == "skip"
|
|
assert r["pending_units"] == 0
|
|
assert calls == ["ZINGEST_T1", "ZINGEST_T1"] # 더 안 불림
|
|
|
|
|
|
def test_llm_disabled(client, monkeypatch):
|
|
c, calls = client
|
|
monkeypatch.setattr(settings, "llm_base_url", "")
|
|
r = c.post("/ingest", json=PAYLOAD).json()
|
|
assert r["summarize"] == "disabled"
|
|
assert calls == []
|