63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from modelforge_api.domain.contracts import ProjectManifest
|
|
from modelforge_api.services.manifest_registry import PROJECT_ROOT, ManifestRegistry
|
|
|
|
|
|
def test_repository_manifests_are_valid_and_model_independent() -> None:
|
|
registry = ManifestRegistry(PROJECT_ROOT / "config")
|
|
assert len(registry.capabilities()) >= 6
|
|
assert len(registry.projects()) == 3
|
|
assert len(registry.benchmarks()) == 2
|
|
assert registry.policies().security.trust_remote_code is False
|
|
for project in registry.projects():
|
|
for binding in project.bindings.values():
|
|
assert "model" not in binding.model_fields_set
|
|
|
|
|
|
def test_project_referencing_missing_contract_is_rejected(tmp_path: Path) -> None:
|
|
(tmp_path / "capabilities").mkdir()
|
|
(tmp_path / "projects").mkdir()
|
|
(tmp_path / "models").mkdir()
|
|
(tmp_path / "projects" / "broken.yaml").write_text(
|
|
"project:\n id: broken\n name: Broken\n description: broken\nbindings:\n rag.missing:\n contract_version: 1\n channel: stable\n priority: production\n",
|
|
encoding="utf-8",
|
|
)
|
|
with pytest.raises(ValueError, match="missing capability"):
|
|
ManifestRegistry(tmp_path).projects()
|
|
|
|
|
|
def test_duplicate_project_manifest_identity_is_rejected(tmp_path: Path) -> None:
|
|
(tmp_path / "capabilities").mkdir()
|
|
projects = tmp_path / "projects"
|
|
projects.mkdir()
|
|
(projects / "first.yaml").write_text(
|
|
"project:\n id: shared\n name: First\n description: First declaration\nbindings: {}\n",
|
|
encoding="utf-8",
|
|
)
|
|
(projects / "second.yaml").write_text(
|
|
"project:\n id: shared\n name: Second\n description: Conflicting declaration\nbindings: {}\n",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="duplicate project manifest identity"):
|
|
ManifestRegistry(tmp_path).projects()
|
|
|
|
|
|
def test_project_manifest_rejects_secret_bearing_extra_fields() -> None:
|
|
payload = {
|
|
"project": {
|
|
"id": "local-consumer",
|
|
"name": "Local Consumer",
|
|
"description": "A non-secret project contract.",
|
|
"service_token": "placeholder-only",
|
|
},
|
|
"bindings": {},
|
|
}
|
|
|
|
with pytest.raises(ValidationError):
|
|
ProjectManifest.model_validate(payload)
|