feat(runtime): implement single-article consolidation runtime and modularize codebase
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
"""Unit tests for atomic file store and manifest generation covering scenarios OUT-001, OUT-011, OUT-012."""
|
||||
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.runtime.storage.file_store import (
|
||||
create_manifest_dict,
|
||||
persist_manifest_atomically,
|
||||
write_file_atomically,
|
||||
)
|
||||
|
||||
|
||||
def test_atomic_file_write_and_verification(tmp_path: Path):
|
||||
dest = tmp_path / "test_doc.md"
|
||||
content = "# Test Document Content"
|
||||
|
||||
hash_hex, byte_count = write_file_atomically(dest, content)
|
||||
assert dest.exists()
|
||||
assert hash_hex == hashlib.sha256(content.encode("utf-8")).hexdigest()
|
||||
assert byte_count == len(content.encode("utf-8"))
|
||||
assert dest.read_text(encoding="utf-8") == content
|
||||
|
||||
|
||||
def test_atomic_file_write_hash_mismatch_raises(tmp_path: Path):
|
||||
dest = tmp_path / "test_doc.md"
|
||||
content = "Hello World"
|
||||
wrong_hash = "0" * 64
|
||||
|
||||
with pytest.raises(ValueError, match="Content hash mismatch"):
|
||||
write_file_atomically(dest, content, expected_hash=wrong_hash)
|
||||
|
||||
|
||||
def test_persist_manifest_atomically(tmp_path: Path):
|
||||
fp = "f" * 64
|
||||
manifest = create_manifest_dict(
|
||||
fingerprint=fp,
|
||||
source_url="https://example.com/1",
|
||||
selected_extractor="trafilatura",
|
||||
final_status="completed_text",
|
||||
generate_markdown=True,
|
||||
markdown_path=str(tmp_path / f"{fp}.md"),
|
||||
markdown_hash="m" * 64,
|
||||
config_version="1.0.0",
|
||||
ecp_classification={
|
||||
"category": "DIRECT_INHERENT",
|
||||
"confidence": 1.0,
|
||||
"rationale": "ok",
|
||||
"evidences": [],
|
||||
},
|
||||
enrichment={"sentiment": "neutral", "tags": ["a", "b", "c"]},
|
||||
provider_versions={
|
||||
"hygiene": {
|
||||
"provider": "groq",
|
||||
"model": "llama-3.1-8b-instant",
|
||||
"role_config_version": "1.0.0",
|
||||
},
|
||||
"enrichment": {
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"role_config_version": "1.0.0",
|
||||
},
|
||||
},
|
||||
model_versions={
|
||||
"runtime_primary": {
|
||||
"provider": "groq",
|
||||
"model": "llama-3.1-8b-instant",
|
||||
"role_config_version": "1.0.0",
|
||||
},
|
||||
"runtime_fallback": {
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"role_config_version": "1.0.0",
|
||||
},
|
||||
},
|
||||
prompt_versions={
|
||||
"article_content_hygiene": {"version": "1.0.0", "hash": "h" * 64},
|
||||
"article_sentiment_tags": {"version": "1.0.0", "hash": "s" * 64},
|
||||
},
|
||||
)
|
||||
|
||||
path, m_hash = persist_manifest_atomically(tmp_path, manifest)
|
||||
assert path.exists()
|
||||
assert path.name == f"{fp}.result.json"
|
||||
assert len(m_hash) == 64
|
||||
Reference in New Issue
Block a user