Files
cowork-local/tests/routing/test_store.py
T
2026-08-09 20:12:05 +07:00

121 lines
3.9 KiB
Python

"""Tests for the assessment store: round-trip, atomic write, history backup."""
from __future__ import annotations
import json
import pytest
from cowork_local.core.routing.models import (
ModelAssessment,
ModelMetadata,
Policy,
ProbeResult,
TaskType,
)
from cowork_local.core.routing.store import AssessmentStore
def _assessment(provider="anthropic", model_id="claude-x", quality=0.8) -> ModelAssessment:
meta = ModelMetadata(
provider=provider,
model_id=model_id,
cost_per_1k_input=0.001,
cost_per_1k_output=0.003,
max_context=200000,
capabilities={"tools"},
)
probe = ProbeResult(latency_ms=400, success=True, quality_score=quality, tokens_out=50)
return ModelAssessment(
metadata=meta,
probes={TaskType.CODING.value: probe},
fit_scores={TaskType.CODING.value: 0.75},
assessed_at="2026-07-22T00:00:00+00:00",
)
@pytest.fixture()
def store(tmp_path):
return AssessmentStore(
store_path=tmp_path / "assessments.json",
history_dir=tmp_path / "history",
)
def test_load_missing_returns_empty(store):
assert store.load() == {}
assert store.last_updated() is None
def test_save_then_load_roundtrip(store):
a = _assessment()
store.save({a.key: a}, Policy.BALANCED)
loaded = store.load()
assert set(loaded) == {a.key}
got = loaded[a.key]
assert got.metadata.model_id == "claude-x"
assert got.metadata.capabilities == {"tools"}
assert got.fit_scores[TaskType.CODING.value] == 0.75
assert got.probes[TaskType.CODING.value].quality_score == 0.8
def test_save_writes_last_updated_and_policy(store):
a = _assessment()
store.save({a.key: a}, Policy.QUALITY, last_updated="2026-07-22T09:00:00+00:00")
assert store.last_updated() == "2026-07-22T09:00:00+00:00"
assert store.policy() == "quality"
def test_overwrite_backs_up_previous_to_history(store):
first = _assessment(quality=0.5)
store.save({first.key: first}, Policy.BALANCED)
assert store.history_files() == [] # nothing existed before the first write
second = _assessment(quality=0.9)
store.save({second.key: second}, Policy.BALANCED)
history = store.history_files()
assert len(history) == 1 # the first write got backed up before the second
backed_up = json.loads(history[0].read_text(encoding="utf-8"))
key = first.key
assert backed_up["results"][key]["probes"][TaskType.CODING.value]["quality_score"] == 0.5
# Live store now holds the second (degraded/improved) version.
assert store.load()[second.key].probes[TaskType.CODING.value].quality_score == 0.9
def test_corrupt_store_loads_as_empty(store):
store.store_path.parent.mkdir(parents=True, exist_ok=True)
store.store_path.write_text("{ this is not valid json ", encoding="utf-8")
assert store.load() == {} # corrupt file must not crash
def test_atomic_write_leaves_no_temp_files(store):
a = _assessment()
store.save({a.key: a}, Policy.BALANCED)
leftovers = list(store.store_path.parent.glob(".assessments-*.tmp"))
assert leftovers == []
def test_one_bad_entry_does_not_hide_good_ones(store):
a = _assessment(model_id="good")
store.save({a.key: a}, Policy.BALANCED)
# Inject a malformed sibling entry directly into the JSON.
raw = json.loads(store.store_path.read_text(encoding="utf-8"))
raw["results"]["anthropic/bad"] = {"metadata": {"oops": True}} # missing required fields
store.store_path.write_text(json.dumps(raw), encoding="utf-8")
loaded = store.load()
assert a.key in loaded
assert "anthropic/bad" not in loaded
def test_prune_history_keeps_newest(store):
a = _assessment()
# 5 overwrites → 4 history snapshots.
for i in range(5):
store.save({a.key: a}, Policy.BALANCED)
assert len(store.history_files()) == 4
store.prune_history(keep=2)
assert len(store.history_files()) == 2