137 lines
5.2 KiB
Python
137 lines
5.2 KiB
Python
import pytest
|
|
from sqlalchemy import create_engine, select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from modelforge_api.persistence.models import (
|
|
Base,
|
|
Capability,
|
|
CapabilityContract,
|
|
Project,
|
|
ProjectBinding,
|
|
)
|
|
from modelforge_api.services.manifest_registry import ManifestRegistry
|
|
from modelforge_api.services.project_registry import sync_project_registry
|
|
|
|
|
|
def test_project_registry_materializes_only_real_contracts_and_is_idempotent() -> None:
|
|
engine = create_engine("sqlite+pysqlite:///:memory:")
|
|
Base.metadata.create_all(engine)
|
|
with Session(engine) as session:
|
|
manifests = ManifestRegistry()
|
|
enabled_capabilities = {"rag.embedding", "rag.reranking", "vision.embedding"}
|
|
for manifest in manifests.capabilities():
|
|
if manifest.capability not in enabled_capabilities:
|
|
continue
|
|
capability = Capability(key=manifest.capability, description=manifest.description)
|
|
session.add(capability)
|
|
session.flush()
|
|
session.add(
|
|
CapabilityContract(
|
|
capability_id=capability.id,
|
|
version=manifest.version,
|
|
input_schema=manifest.input_schema,
|
|
output_schema=manifest.output_schema,
|
|
contract=manifest.model_dump(mode="json"),
|
|
upgrade_class=manifest.upgrade_class.value,
|
|
)
|
|
)
|
|
session.commit()
|
|
|
|
first = sync_project_registry(session, manifests)
|
|
second = sync_project_registry(session, manifests)
|
|
|
|
assert first.projects_created == 3
|
|
assert first.bindings_created == 3
|
|
assert first.unavailable_contracts
|
|
assert second.projects_created == 0
|
|
assert second.bindings_created == 0
|
|
assert session.query(Project).count() == 3
|
|
bindings = session.execute(
|
|
select(Project.key, Capability.key)
|
|
.join(ProjectBinding, ProjectBinding.project_id == Project.id)
|
|
.join(
|
|
CapabilityContract,
|
|
CapabilityContract.id == ProjectBinding.capability_contract_id,
|
|
)
|
|
.join(Capability, Capability.id == CapabilityContract.capability_id)
|
|
).all()
|
|
assert set(bindings) == {
|
|
("examplerag", "rag.embedding"),
|
|
("examplerag", "rag.reranking"),
|
|
("examplevision", "vision.embedding"),
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize("declared_stability", ["planned", "blocked"])
|
|
def test_project_registry_skips_unavailable_capabilities_and_preserves_operator_bindings(
|
|
declared_stability: str, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
engine = create_engine("sqlite+pysqlite:///:memory:")
|
|
Base.metadata.create_all(engine)
|
|
with Session(engine) as session:
|
|
manifests = ManifestRegistry()
|
|
capability_manifest = next(
|
|
item
|
|
for item in manifests.capabilities()
|
|
if item.capability == "assistant.general" and item.version == 1
|
|
)
|
|
project_manifest = next(
|
|
item for item in manifests.projects() if item.project.id == "example-ops"
|
|
)
|
|
capability_manifest = capability_manifest.model_copy(
|
|
update={
|
|
"estate": capability_manifest.estate.model_copy(
|
|
update={"stability": declared_stability}
|
|
)
|
|
}
|
|
)
|
|
monkeypatch.setattr(manifests, "capabilities", lambda: [capability_manifest])
|
|
monkeypatch.setattr(manifests, "projects", lambda: [project_manifest])
|
|
|
|
capability = Capability(
|
|
key=capability_manifest.capability, description=capability_manifest.description
|
|
)
|
|
session.add(capability)
|
|
session.flush()
|
|
contract = CapabilityContract(
|
|
capability_id=capability.id,
|
|
version=capability_manifest.version,
|
|
input_schema=capability_manifest.input_schema,
|
|
output_schema=capability_manifest.output_schema,
|
|
contract=capability_manifest.model_dump(mode="json"),
|
|
upgrade_class=capability_manifest.upgrade_class.value,
|
|
)
|
|
session.add(contract)
|
|
session.commit()
|
|
|
|
first = sync_project_registry(session, manifests)
|
|
|
|
assert first.bindings_created == 0
|
|
assert session.scalar(select(ProjectBinding.id)) is None
|
|
assert [
|
|
(
|
|
item.project_key,
|
|
item.capability,
|
|
item.contract_version,
|
|
item.declared_stability,
|
|
)
|
|
for item in first.unavailable_bindings
|
|
] == [("example-ops", "assistant.general", 1, declared_stability)]
|
|
|
|
project = session.scalar(select(Project).where(Project.key == "example-ops"))
|
|
assert project is not None
|
|
operator_binding = ProjectBinding(
|
|
project_id=project.id,
|
|
capability_contract_id=contract.id,
|
|
channel="stable",
|
|
priority="interactive",
|
|
)
|
|
session.add(operator_binding)
|
|
session.commit()
|
|
operator_binding_id = operator_binding.id
|
|
|
|
second = sync_project_registry(session, manifests)
|
|
|
|
assert second.bindings_created == 0
|
|
assert session.scalar(select(ProjectBinding.id)) == operator_binding_id
|