llm-ingestion-okf/tests/test_golden.py
Kjell Tore Guttormsen 2504011010 feat(okf-v0.2): D5 — the v0.2 golden fixture, with okf_version in root frontmatter
Placement settled by catalog's own reading of upstream at the pinned commit
3fcbb9f: SS8:509-510 and SS12:773-775 both put `okf_version` in a bundle-root
`index.md` frontmatter block, and SS12 calls it the only place frontmatter is
permitted in an index. Catalog's spec says the opposite about the same file;
that divergence is theirs against upstream, and we conform to upstream.

The value never touches a profile. `OKF_V0_2.index.root_frontmatter` names the
key; the caller supplies the value through a new keyword-only
`root_frontmatter_values` mapping. That keeps V4/V-A5 intact - `okf_version`'s
value tracks the upstream Google version and belongs to catalog (E1), so a
constant here would claim a decision we do not own and would have to be chased
on every upstream release. In the fixture the value is fixture DATA
(`okf-version.txt`), not a literal in our source.

Ordering comes from the policy, not the caller's mapping: a dict preserves
insertion order, so two callers passing the same keys would otherwise emit
different bytes. A key the policy does not name is refused fail-fast, before
any disk mutation. Omitting the argument emits no block at all - SS12 is a MAY
and none of upstream's four reference bundles declares the key.

The block is written only when the index is CREATED, so a re-run into an
existing bundle stays byte-identical (A-E5).

Raw-byte assertions rather than parsed ones, on the committed fixture as well
as on fresh runs: catalog measured that a quoted value fails their shape regex
with exit 1 and that a BOM hides the marker while still exiting 0.
`yaml.safe_load` returns "0.2" either way and strips a BOM first, so a parsed
assertion masks exactly those two defects. Asserting the frozen fixture catches
what a self-comparison cannot - regenerating from a broken emitter moves both
sides together.

A-E6 is now placement-explicit (promised catalog in 99cf987), and separates the
two byte properties: BOM-free is a property of the file, unquoted is a property
of CATALOG'S GATE and not of OKF v0.2 - upstream's own SS12 example is quoted,
so their gate rejects the spec's canonical form.

README gains the upstream-version section it was missing; CLAUDE.md gains the
mechanism behind "no profile hard-codes an upstream version": a profile names a
key, a caller owns its value.

550 -> 559 tests. test_profile_threading's `OKF_V0_2.index is DEFAULT.index`
assertion is replaced rather than deleted: object identity was a proxy for "the
shipped profiles differ in no NAME-bearing field", which is what makes the
synthetic test profile necessary, so the guard now asserts that directly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dgkSPjkLpACjMayd9R5jx
2026-07-31 17:27:48 +02:00

89 lines
3.2 KiB
Python

"""Golden byte-for-byte conformance (ingest-spec §11) — load-bearing.
Each golden case is re-materialized into a fresh directory and compared
against its expected-bundle file by file, byte for byte. The test MUST fail
when any byte of an expected bundle diverges. Offline, credential-free:
the sql fixture is a committed database file, the http case runs against
mock payloads served from its fixture directory.
"""
from __future__ import annotations
from pathlib import Path
import pytest
from llm_ingestion_okf.materialize import materialize_bundle
from llm_ingestion_okf.profiles import OKF_V0_2
EXAMPLES = Path(__file__).parent.parent / "examples"
INGESTED_AT_NAME = "ingested-at.txt"
OKF_VERSION_NAME = "okf-version.txt"
def fixture_backed_get(fixture_dir: Path) -> object:
"""A mock transport serving fixture/{query path} — never a socket."""
def get(url: str, credential: str | None) -> str:
path = url.rsplit("/", 1)[-1]
return (fixture_dir / path).read_text(encoding="utf-8")
return get
def materialize_case(case_dir: Path, out_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None:
ingested_at = (case_dir / INGESTED_AT_NAME).read_text(encoding="utf-8").strip()
if case_dir.name.endswith("sql"):
monkeypatch.setenv("OKF_GOLDEN_SQL_DB", str(case_dir / "fixture" / "metrics.db"))
materialize_bundle(case_dir / "manifest.json", out_dir, ingested_at)
elif case_dir.name.endswith("http"):
materialize_bundle(
case_dir / "manifest.json",
out_dir,
ingested_at,
allow_network=True,
http_get=fixture_backed_get(case_dir / "fixture"), # type: ignore[arg-type]
)
elif case_dir.name.endswith("okf-v0-2"):
# The declared version is fixture DATA, read from the case, never a
# constant in this file. Its value tracks the upstream Google version
# and belongs to catalog (E1); a literal here would be this repo
# claiming a decision it does not own, and the golden would then have
# to be chased on every upstream release.
materialize_bundle(
case_dir / "manifest.json",
out_dir,
ingested_at,
profile=OKF_V0_2,
root_frontmatter_values={
"okf_version": (case_dir / OKF_VERSION_NAME).read_text(encoding="utf-8").strip()
},
)
else:
materialize_bundle(case_dir / "manifest.json", out_dir, ingested_at)
@pytest.mark.parametrize(
"case",
[
"ingest-golden-file",
"ingest-golden-sql",
"ingest-golden-http",
"ingest-golden-okf-v0-2",
],
)
def test_golden_case_byte_for_byte(
case: str, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
case_dir = EXAMPLES / case
expected_dir = case_dir / "expected-bundle"
out_dir = tmp_path / "bundle"
materialize_case(case_dir, out_dir, monkeypatch)
expected_files = sorted(path.name for path in expected_dir.iterdir())
actual_files = sorted(path.name for path in out_dir.iterdir())
assert actual_files == expected_files
for name in expected_files:
assert (out_dir / name).read_bytes() == (expected_dir / name).read_bytes(), (
f"{case}/{name} diverges from the golden bytes"
)