feat(runtime): implement single-article consolidation runtime and modularize codebase
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
"""Crash recovery and state reconciliation integration tests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from src.runtime.cli.reconcile import reconcile_runtime
|
||||
from src.runtime.storage.sqlite_store import SQLiteStore
|
||||
|
||||
|
||||
def test_reconcile_resolves_crash_mismatch(tmp_path: Path):
|
||||
"""Simulates a crash where a Markdown file and manifest were written, but SQLite status remained in 'received' state.
|
||||
|
||||
Asserts:
|
||||
1. Reconcile detects the completed artifact.
|
||||
2. Reconcile calculates and verifies the SHA-256 hash.
|
||||
3. Reconcile updates SQLite status to 'completed_text' with matching payload.
|
||||
"""
|
||||
db_path = tmp_path / "state.db"
|
||||
out_dir = tmp_path / "out"
|
||||
out_dir.mkdir()
|
||||
|
||||
base_cfg = json.loads(Path("runtime_config.local.json").read_text(encoding="utf-8"))
|
||||
base_cfg["paths"]["sqlite_db"] = str(db_path)
|
||||
base_cfg["paths"]["output_dir"] = str(out_dir)
|
||||
|
||||
cfg_file = tmp_path / "cfg.json"
|
||||
cfg_file.write_text(json.dumps(base_cfg, indent=2), encoding="utf-8")
|
||||
|
||||
store = SQLiteStore(db_path)
|
||||
fp = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
|
||||
|
||||
# Step 1: SQLite has received status
|
||||
store.claim_or_get_execution(fp, "https://example.com/test", "trafilatura", "1.0.0")
|
||||
|
||||
# Step 2: Disk has completed markdown and manifest
|
||||
md_content = "---\ntitle: Reconciled Article\n---\n\nContent here."
|
||||
md_file = out_dir / f"{fp}.md"
|
||||
md_file.write_text(md_content, encoding="utf-8")
|
||||
md_hash = hashlib.sha256(md_content.encode("utf-8")).hexdigest()
|
||||
|
||||
manifest_data = {
|
||||
"manifest_version": "1.0.0",
|
||||
"fingerprint": fp,
|
||||
"status": "completed_text",
|
||||
"artifacts": {
|
||||
"markdown_path": str(md_file),
|
||||
"markdown_sha256": md_hash,
|
||||
"manifest_path": str(out_dir / f"{fp}.result.json"),
|
||||
},
|
||||
}
|
||||
manifest_file = out_dir / f"{fp}.result.json"
|
||||
manifest_file.write_text(json.dumps(manifest_data, indent=2), encoding="utf-8")
|
||||
|
||||
# Step 3: Run reconciliation
|
||||
report = reconcile_runtime(cfg_file)
|
||||
|
||||
assert report["divergent_states_recovered"] == 1
|
||||
|
||||
# Step 4: Verify DB updated to completed_text
|
||||
record = store.get_execution(fp)
|
||||
assert record is not None
|
||||
assert record["current_status"] == "completed_text"
|
||||
Reference in New Issue
Block a user