| import json |
| import subprocess |
| import sys |
| from pathlib import Path |
|
|
|
|
| ROOT = Path(__file__).resolve().parent.parent |
| SCRIPT = ROOT / "scripts" / "build_preference_pairs.py" |
| OUT = ROOT / "data" / "test_pairs.jsonl" |
|
|
|
|
| REQUIRED_FIELDS = { |
| "prompt", "chosen", "rejected", "scenario", |
| "step", "issue_id", "is_attack", "kind", |
| } |
|
|
|
|
| def _run_builder(max_pairs: int = 20) -> None: |
| if OUT.exists(): |
| OUT.unlink() |
| cmd = [ |
| sys.executable, str(SCRIPT), |
| "--max-pairs", str(max_pairs), |
| "--out", str(OUT), |
| ] |
| res = subprocess.run(cmd, cwd=str(ROOT), capture_output=True, text=True) |
| assert res.returncode == 0, f"builder failed: {res.stderr}\nSTDOUT:{res.stdout}" |
|
|
|
|
| def test_preference_pairs_smoke(): |
| _run_builder(max_pairs=20) |
| assert OUT.exists(), f"output file not written: {OUT}" |
| lines = OUT.read_text(encoding="utf-8").strip().splitlines() |
| assert len(lines) == 20, f"expected 20 lines, got {len(lines)}" |
| for i, line in enumerate(lines): |
| rec = json.loads(line) |
| missing = REQUIRED_FIELDS - rec.keys() |
| assert not missing, f"line {i} missing fields: {missing}" |
| assert rec["chosen"] != rec["rejected"], f"line {i} has chosen == rejected" |
| assert isinstance(rec["prompt"], str) and rec["prompt"], f"line {i} empty prompt" |
| assert rec["kind"] in {"contrastive_reasoning", "wrong_action_confident"} |
| json.loads(rec["chosen"]) |
| json.loads(rec["rejected"]) |
|
|
|
|
| if __name__ == "__main__": |
| test_preference_pairs_smoke() |
| print("PASS test_preference_pairs_smoke") |
|
|