"""rerank 프로토콜 정규화 단위 테스트 — 2노드 이관 P1-4 (llama.cpp /v1/rerank). 순수 함수(ai/rerank_protocol.py)만 대상 — HTTP/DB 의존 없음. 실행: PYTHONPATH=app pytest tests/test_rerank_protocol.py """ import json from pathlib import Path from ai.rerank_protocol import normalize_llamacpp_rerank FIXTURES = Path(__file__).parent / "fixtures" def test_normalize_llamacpp_shape_and_desc_sort(): payload = { "model": "bge-reranker-v2-m3", "results": [ {"index": 0, "relevance_score": 0.12}, {"index": 1, "relevance_score": 2.21}, {"index": 2, "relevance_score": -1.5}, ], } out = normalize_llamacpp_rerank(payload) # TEI 계약: [{"index","score"}] score 내림차순 assert [r["index"] for r in out] == [1, 0, 2] assert all(set(r) == {"index", "score"} for r in out) assert out[0]["score"] == 2.21 def test_normalize_llamacpp_missing_fields_skipped(): payload = { "results": [ {"index": 0}, # relevance_score 없음 → 버림 {"relevance_score": 1.0}, # index 없음 → 버림 {"index": 3, "relevance_score": 0.5}, ] } assert normalize_llamacpp_rerank(payload) == [{"index": 3, "score": 0.5}] def test_normalize_llamacpp_empty_and_absent_results(): assert normalize_llamacpp_rerank({}) == [] assert normalize_llamacpp_rerank({"results": []}) == [] def test_tei_fixture_shape_is_already_contract(): """TEI 캡처 fixture(Phase 2B G0-1 spec 박제)의 실응답이 정규화 없이 계약 형태임을 확인.""" doc = json.loads((FIXTURES / "tei_rerank_response.json").read_text()) captured = doc["captured_responses"]["baseline_bge_v2_m3"] assert isinstance(captured, list) and captured assert {"index", "score"} <= set(captured[0]) # spec 문자열도 계약과 일치 (score desc 정렬 포함) assert "index" in doc["response_shape"] and "score" in doc["response_shape"]