113 lines
3.8 KiB
Python
113 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
"""test_contextual_prefix.py — hermetic tests for scripts/contextual-prefix.py.
|
|
|
|
Covers the Haiku cache-floor decision (cache_control_for). The network paths
|
|
(tier-1 Anthropic API, tier-2 claude CLI) are egress-gated and excluded from
|
|
hermetic tests by design; only the pure floor logic is exercised here. No
|
|
network, no LLM, no ollama. Pure stdlib.
|
|
|
|
Usage:
|
|
python3 tests/test_contextual_prefix.py
|
|
"""
|
|
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
HELPER = ROOT / "scripts" / "contextual-prefix.py"
|
|
|
|
spec = importlib.util.spec_from_file_location("contextual_prefix", HELPER)
|
|
cp = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(cp)
|
|
|
|
|
|
class Fail(SystemExit):
|
|
pass
|
|
|
|
|
|
def assert_eq(label, expected, actual):
|
|
if expected != actual:
|
|
raise Fail(f"FAIL {label}: expected {expected!r}, got {actual!r}")
|
|
print(f"OK {label}")
|
|
|
|
|
|
def assert_true(label, cond):
|
|
if not cond:
|
|
raise Fail(f"FAIL {label}")
|
|
print(f"OK {label}")
|
|
|
|
|
|
# ─── Below the floor → no cache_control (silent no-op avoided) ───────────────
|
|
def test_below_floor_returns_none():
|
|
body = "x" * (cp.HAIKU_CACHE_MIN_CHARS - 1)
|
|
assert_eq("body 1 char below floor → None", None, cp.cache_control_for(body))
|
|
|
|
|
|
def test_empty_body_returns_none():
|
|
assert_eq("empty body → None", None, cp.cache_control_for(""))
|
|
|
|
|
|
# ─── At / above the floor → ephemeral cache_control ──────────────────────────
|
|
def test_at_floor_returns_ephemeral():
|
|
body = "x" * cp.HAIKU_CACHE_MIN_CHARS
|
|
assert_eq("body exactly at floor → ephemeral",
|
|
{"type": "ephemeral"}, cp.cache_control_for(body))
|
|
|
|
|
|
def test_above_floor_returns_ephemeral():
|
|
body = "x" * (cp.HAIKU_CACHE_MIN_CHARS * 3)
|
|
assert_eq("body well above floor → ephemeral",
|
|
{"type": "ephemeral"}, cp.cache_control_for(body))
|
|
|
|
|
|
# ─── Integration: built payload attaches cache_control only above the floor ──
|
|
def test_payload_attaches_cache_control_by_body_size():
|
|
"""Mock the network. Assert the API payload attaches cache_control to the
|
|
page block only when the body clears the floor, and the multi-line model
|
|
reply is truncated to one line. No network, no LLM."""
|
|
captured = {}
|
|
|
|
class _Resp:
|
|
def __init__(self, d):
|
|
self._d = json.dumps(d).encode()
|
|
|
|
def read(self):
|
|
return self._d
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *a):
|
|
return False
|
|
|
|
def _fake_urlopen(req, timeout=None):
|
|
captured["body"] = json.loads(req.data.decode())
|
|
return _Resp({
|
|
"content": [{"type": "text", "text": "one situating line.\nIGNORED"}],
|
|
"usage": {"cache_creation_input_tokens": 7, "cache_read_input_tokens": 3},
|
|
})
|
|
|
|
with mock.patch.object(cp.urllib.request, "urlopen", _fake_urlopen):
|
|
out = cp.anthropic_api_prefix("KEY", "T", "x" * cp.HAIKU_CACHE_MIN_CHARS, "chunk")
|
|
assert_eq("multi-line reply truncated to one line", "one situating line.", out)
|
|
assert_true("above-floor body attaches cache_control",
|
|
"cache_control" in captured["body"]["system"][1])
|
|
cp.anthropic_api_prefix("KEY", "T", "tiny", "chunk")
|
|
assert_true("below-floor body omits cache_control",
|
|
"cache_control" not in captured["body"]["system"][1])
|
|
|
|
|
|
def main():
|
|
print("=== test_contextual_prefix.py ===")
|
|
test_below_floor_returns_none()
|
|
test_empty_body_returns_none()
|
|
test_at_floor_returns_ephemeral()
|
|
test_above_floor_returns_ephemeral()
|
|
test_payload_attaches_cache_control_by_body_size()
|
|
print("\nAll contextual-prefix tests passed.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|