feat(examples): ship the §11 golden fixtures with byte-exact conformance
TDD step 8: three golden cases per the §11 format (manifest.json, fixture/, ingested-at.txt, expected-bundle/) — ingest-golden-file and ingest-golden-sql are the conformance MUSTs; ingest-golden-http documents and exercises the optional extension against mock payloads. The conformance test re-materializes each case into a fresh directory and compares byte for byte; offline and credential-free (the sql fixture is a committed database file, http never opens a socket). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
This commit is contained in:
parent
ab1fa4d999
commit
9dd86b1b18
19 changed files with 225 additions and 0 deletions
22
examples/README.md
Normal file
22
examples/README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Golden extractions (ingest-spec §11)
|
||||||
|
|
||||||
|
One directory per case, `ingest-golden-{source type}/`, each containing:
|
||||||
|
|
||||||
|
| Entry | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `manifest.json` | The manifest under test. |
|
||||||
|
| `fixture/` | The source content (CSV catalogue, sqlite database, or mock payloads). |
|
||||||
|
| `ingested-at.txt` | The fixed timestamp, one line, §5 format. |
|
||||||
|
| `expected-bundle/` | The expected materialized bundle, compared byte for byte. |
|
||||||
|
|
||||||
|
`ingest-golden-file` and `ingest-golden-sql` are the conformance MUSTs. The
|
||||||
|
`http` source type is an OPTIONAL extension point (spec §1); this repository
|
||||||
|
implements it, and `ingest-golden-http` exercises it against the mock payloads
|
||||||
|
in its `fixture/` directory — the conformance suite never opens a socket and
|
||||||
|
runs without credentials (§11). For the `sql` case, the test sets the
|
||||||
|
`OKF_GOLDEN_SQL_DB` environment variable to the fixture database path; for the
|
||||||
|
`http` case, the injected mock transport serves `fixture/{query path}`.
|
||||||
|
|
||||||
|
The suite (`tests/test_golden.py`) re-materializes each case into a fresh
|
||||||
|
directory and compares the result against `expected-bundle/` file by file,
|
||||||
|
byte for byte — the load-bearing golden-regression seam (§11).
|
||||||
3
examples/ingest-golden-file/expected-bundle/index.md
Normal file
3
examples/ingest-golden-file/expected-bundle/index.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Golden file-source bundle: orders and products extracted from a CSV catalogue.
|
||||||
|
- [Orders](ingest-orders.md)
|
||||||
|
- [Products](ingest-products.md)
|
||||||
15
examples/ingest-golden-file/expected-bundle/ingest-orders.md
Normal file
15
examples/ingest-golden-file/expected-bundle/ingest-orders.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
type: dataset
|
||||||
|
title: Orders
|
||||||
|
source_system: golden-catalogue
|
||||||
|
source_query: orders.csv
|
||||||
|
ingested_at: 2026-07-16T12:00:00Z
|
||||||
|
ingest_manifest: manifest@37674ac20059e788
|
||||||
|
generated: true
|
||||||
|
---
|
||||||
|
|
||||||
|
| order_id | customer | total |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 1001 | Alice | 250.5 |
|
||||||
|
| 1002 | Bob | 99.9 |
|
||||||
|
| 1003 | Carol | 0.1 |
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
type: dataset
|
||||||
|
title: Products
|
||||||
|
source_system: golden-catalogue
|
||||||
|
source_query: products.csv
|
||||||
|
ingested_at: 2026-07-16T12:00:00Z
|
||||||
|
ingest_manifest: manifest@37674ac20059e788
|
||||||
|
generated: true
|
||||||
|
---
|
||||||
|
|
||||||
|
| sku | name | note |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| A-1 | Pipe\|Product | has\|pipe |
|
||||||
|
| B-2 | Back\\slash | line1 line2 |
|
||||||
|
| C-3 | Plain | |
|
||||||
4
examples/ingest-golden-file/fixture/orders.csv
Normal file
4
examples/ingest-golden-file/fixture/orders.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
order_id,customer,total
|
||||||
|
1001,Alice,250.5
|
||||||
|
1002,Bob,99.9
|
||||||
|
1003,Carol,0.1
|
||||||
|
5
examples/ingest-golden-file/fixture/products.csv
Normal file
5
examples/ingest-golden-file/fixture/products.csv
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
sku,name,note
|
||||||
|
A-1,Pipe|Product,has|pipe
|
||||||
|
B-2,Back\slash,"line1
|
||||||
|
line2"
|
||||||
|
C-3,Plain,
|
||||||
|
1
examples/ingest-golden-file/ingested-at.txt
Normal file
1
examples/ingest-golden-file/ingested-at.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
2026-07-16T12:00:00Z
|
||||||
25
examples/ingest-golden-file/manifest.json
Normal file
25
examples/ingest-golden-file/manifest.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 1,
|
||||||
|
"source": {
|
||||||
|
"type": "file",
|
||||||
|
"id": "golden-catalogue",
|
||||||
|
"root": "fixture"
|
||||||
|
},
|
||||||
|
"bundle_summary": "Golden file-source bundle: orders and products extracted from a CSV catalogue.",
|
||||||
|
"extractions": [
|
||||||
|
{
|
||||||
|
"id": "orders",
|
||||||
|
"title": "Orders",
|
||||||
|
"query": "orders.csv",
|
||||||
|
"okf_type": "dataset",
|
||||||
|
"max_rows": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "products",
|
||||||
|
"title": "Products",
|
||||||
|
"query": "products.csv",
|
||||||
|
"okf_type": "dataset",
|
||||||
|
"max_rows": 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
2
examples/ingest-golden-http/expected-bundle/index.md
Normal file
2
examples/ingest-golden-http/expected-bundle/index.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Golden http-source bundle: a status payload fetched from a mock endpoint.
|
||||||
|
- [Status](ingest-status.md)
|
||||||
13
examples/ingest-golden-http/expected-bundle/ingest-status.md
Normal file
13
examples/ingest-golden-http/expected-bundle/ingest-status.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
type: dataset
|
||||||
|
title: Status
|
||||||
|
source_system: golden-api
|
||||||
|
source_query: /status.json
|
||||||
|
ingested_at: 2026-07-16T12:00:00Z
|
||||||
|
ingest_manifest: manifest@826dbd7dec4d4c79
|
||||||
|
generated: true
|
||||||
|
---
|
||||||
|
|
||||||
|
```
|
||||||
|
{"status": "ok", "count": 3}
|
||||||
|
```
|
||||||
1
examples/ingest-golden-http/fixture/status.json
Normal file
1
examples/ingest-golden-http/fixture/status.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"status": "ok", "count": 3}
|
||||||
1
examples/ingest-golden-http/ingested-at.txt
Normal file
1
examples/ingest-golden-http/ingested-at.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
2026-07-16T12:00:00Z
|
||||||
18
examples/ingest-golden-http/manifest.json
Normal file
18
examples/ingest-golden-http/manifest.json
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 1,
|
||||||
|
"source": {
|
||||||
|
"type": "http",
|
||||||
|
"id": "golden-api",
|
||||||
|
"base_url": "https://golden.example.test"
|
||||||
|
},
|
||||||
|
"bundle_summary": "Golden http-source bundle: a status payload fetched from a mock endpoint.",
|
||||||
|
"extractions": [
|
||||||
|
{
|
||||||
|
"id": "status",
|
||||||
|
"title": "Status",
|
||||||
|
"query": "/status.json",
|
||||||
|
"okf_type": "dataset",
|
||||||
|
"max_rows": 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
2
examples/ingest-golden-sql/expected-bundle/index.md
Normal file
2
examples/ingest-golden-sql/expected-bundle/index.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Golden sql-source bundle: metrics extracted from a sqlite fixture database.
|
||||||
|
- [Metrics](ingest-metrics.md)
|
||||||
15
examples/ingest-golden-sql/expected-bundle/ingest-metrics.md
Normal file
15
examples/ingest-golden-sql/expected-bundle/ingest-metrics.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
type: dataset
|
||||||
|
title: Metrics
|
||||||
|
source_system: golden-db
|
||||||
|
source_query: SELECT id, name, value, comment FROM metrics ORDER BY id
|
||||||
|
ingested_at: 2026-07-16T12:00:00Z
|
||||||
|
ingest_manifest: manifest@93a04cce66d99b53
|
||||||
|
generated: true
|
||||||
|
---
|
||||||
|
|
||||||
|
| id | name | value | comment |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1 | throughput | 12.5 | steady\|rate |
|
||||||
|
| 2 | latency | 0.1 | |
|
||||||
|
| 3 | errors | 3.0 | |
|
||||||
BIN
examples/ingest-golden-sql/fixture/metrics.db
Normal file
BIN
examples/ingest-golden-sql/fixture/metrics.db
Normal file
Binary file not shown.
1
examples/ingest-golden-sql/ingested-at.txt
Normal file
1
examples/ingest-golden-sql/ingested-at.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
2026-07-16T12:00:00Z
|
||||||
18
examples/ingest-golden-sql/manifest.json
Normal file
18
examples/ingest-golden-sql/manifest.json
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 1,
|
||||||
|
"source": {
|
||||||
|
"type": "sql",
|
||||||
|
"id": "golden-db",
|
||||||
|
"connection_ref": "OKF_GOLDEN_SQL_DB"
|
||||||
|
},
|
||||||
|
"bundle_summary": "Golden sql-source bundle: metrics extracted from a sqlite fixture database.",
|
||||||
|
"extractions": [
|
||||||
|
{
|
||||||
|
"id": "metrics",
|
||||||
|
"title": "Metrics",
|
||||||
|
"query": "SELECT id, name, value, comment FROM metrics ORDER BY id",
|
||||||
|
"okf_type": "dataset",
|
||||||
|
"max_rows": 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
64
tests/test_golden.py
Normal file
64
tests/test_golden.py
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
"""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
|
||||||
|
|
||||||
|
EXAMPLES = Path(__file__).parent.parent / "examples"
|
||||||
|
INGESTED_AT_NAME = "ingested-at.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]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
materialize_bundle(case_dir / "manifest.json", out_dir, ingested_at)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("case", ["ingest-golden-file", "ingest-golden-sql", "ingest-golden-http"])
|
||||||
|
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"
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue