"""Contract tests for runtime-config.schema.json.""" from __future__ import annotations import json from pathlib import Path import jsonschema import pytest from src.runtime.core.config import create_schema_registry, load_runtime_config, load_schema def test_runtime_config_schema_validation_valid(): schema = load_schema("runtime-config.schema.json") registry = create_schema_registry() validator = jsonschema.Draft202012Validator(schema, registry=registry) valid_config = { "config_version": "1.0.0", "paths": {"output_dir": "out/articles", "sqlite_db": "out/runtime.db"}, "roles": { "runtime_primary": { "role_config_version": "1.0.0", "provider": "groq", "model": "llama-3.1-8b-instant", "endpoint_url": "https://api.groq.com/openai/v1", "timeout_seconds": 30, "max_retries": 3, "parameters": {"temperature": 0.0}, "hygiene_prompt_version": "1.0.0", "hygiene_schema_version": "1.0.0", "enrichment_prompt_version": "1.0.0", "enrichment_schema_version": "1.0.0", }, "runtime_fallback": { "role_config_version": "1.0.0", "provider": "deepseek", "model": "deepseek-chat", "endpoint_url": "https://api.deepseek.com/v1", "timeout_seconds": 30, "max_retries": 3, "parameters": {"temperature": 0.0}, "hygiene_prompt_version": "1.0.0", "hygiene_schema_version": "1.0.0", "enrichment_prompt_version": "1.0.0", "enrichment_schema_version": "1.0.0", }, }, "prompts": { "article_content_hygiene": { "path": "prompts/article_content_hygiene.v1.txt", "version": "1.0.0", "hash": "0000000000000000000000000000000000000000000000000000000000000000", }, "article_sentiment_tags": { "path": "prompts/article_sentiment_tags.v1.txt", "version": "1.0.0", "hash": "0000000000000000000000000000000000000000000000000000000000000000", }, }, "ecp": { "canonical_schema_reference": "specs/006-article-consolidation-runtime/contracts/ecp-snapshot.schema.json", "classifier_module": "src.classifier.InherenceClassifier", }, "limits": {"max_input_bytes": 1048576, "context_strategy": "fail_before_provider"}, "pricing": { "primary_input_1k": 0.00005, "primary_output_1k": 0.00008, "fallback_input_1k": 0.00014, "fallback_output_1k": 0.00028, }, "langfuse": {"environment": "local", "trace_content_policy": "metadata_only"}, "sqlite": {"busy_timeout_ms": 5000}, } errors = list(validator.iter_errors(valid_config)) assert len(errors) == 0, f"Schema validation errors: {[e.message for e in errors]}" def test_runtime_config_fixture_loads_successfully(): config = load_runtime_config("runtime_config.local.json") assert config.config_version == "1.0.0" assert "runtime_primary" in config.roles assert "runtime_fallback" in config.roles assert config.roles["runtime_primary"].model == "llama-3.1-8b-instant" def test_runtime_config_rejects_powerful_models(tmp_path: Path): valid_base = json.loads(Path("runtime_config.local.json").read_text(encoding="utf-8")) valid_base["roles"]["runtime_primary"]["model"] = "gpt-4o" # Forbidden powerful model cfg_file = tmp_path / "invalid_cfg.json" cfg_file.write_text(json.dumps(valid_base), encoding="utf-8") with pytest.raises(ValueError, match="Forbidden powerful model"): load_runtime_config(cfg_file)