80 lines
3.7 KiB
Python
80 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
import copy
|
|
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import Session
|
|
|
|
from modelforge_api.domain.configuration import ConfigurationApply, ConfigurationChange
|
|
from modelforge_api.persistence.models import Base
|
|
from modelforge_api.services.audit import AuditContext, AuditWriter
|
|
from modelforge_api.services.configuration_changes import ConfigurationService
|
|
from modelforge_api.services.recovery_fingerprint import (
|
|
CONFIGURATION_TABLES,
|
|
SELECTED_COMPARISON_SCHEMA,
|
|
_without_creative,
|
|
_without_lab_execution,
|
|
_without_managed_identities,
|
|
_without_model_changes,
|
|
_without_model_updates,
|
|
_without_projects,
|
|
_without_secrets,
|
|
_without_selected_comparisons,
|
|
audit_fingerprint_differences_are_compatible,
|
|
fingerprint_compatibility,
|
|
semantic_fingerprint,
|
|
)
|
|
from modelforge_api.settings import Settings
|
|
|
|
|
|
def test_upgrade_introduces_only_empty_configuration_and_current_restore_preserves_every_revision() -> None:
|
|
engine = create_engine("sqlite://")
|
|
Base.metadata.create_all(engine)
|
|
with Session(engine) as session:
|
|
AuditWriter(session, "operator", "baseline").write("test.baseline", "configuration", None, {})
|
|
session.commit()
|
|
fresh = semantic_fingerprint(session.connection())
|
|
previous = _without_lab_execution(_without_projects(
|
|
_without_managed_identities(
|
|
_without_secrets(
|
|
_without_model_updates(
|
|
_without_selected_comparisons(
|
|
_without_creative(_without_model_changes(copy.deepcopy(fresh)))
|
|
)
|
|
)
|
|
)
|
|
),
|
|
legacy=True,
|
|
))
|
|
previous["tables"] = {key: value for key, value in previous["tables"].items() if key not in CONFIGURATION_TABLES}
|
|
previous["physical_tables"] = [name for name in previous["physical_tables"] if name not in CONFIGURATION_TABLES]
|
|
upgrade = fingerprint_compatibility(previous, fresh, source_schema_revision="20260830_0024")
|
|
assert upgrade.compatible
|
|
assert audit_fingerprint_differences_are_compatible(previous, fresh, upgrade)
|
|
subject = ConfigurationService(session, Settings(_env_file=None), AuditContext("operator", "config", "restore-test"))
|
|
change = ConfigurationChange(expected_revision=0, changes={"gateway_max_batch_size": 2})
|
|
preview = subject.preview(change)
|
|
subject.apply(ConfigurationApply(**change.model_dump(), preview_digest=preview.preview_digest, confirm=True))
|
|
configured = semantic_fingerprint(session.connection())
|
|
configured_0033 = _without_lab_execution(_without_model_changes(configured))
|
|
assert not fingerprint_compatibility(previous, configured, source_schema_revision="20260830_0024").compatible
|
|
current = fingerprint_compatibility(
|
|
configured_0033,
|
|
configured_0033,
|
|
source_schema_revision=SELECTED_COMPARISON_SCHEMA,
|
|
)
|
|
assert current.compatible
|
|
assert audit_fingerprint_differences_are_compatible(configured_0033, configured_0033, current)
|
|
for table in CONFIGURATION_TABLES:
|
|
altered = copy.deepcopy(configured_0033)
|
|
altered["tables"][table]["digest"] = "0" * 64
|
|
assert not audit_fingerprint_differences_are_compatible(configured_0033, altered, current)
|
|
missing = copy.deepcopy(configured_0033)
|
|
missing["tables"].pop(table)
|
|
assert not fingerprint_compatibility(
|
|
configured_0033,
|
|
missing,
|
|
source_schema_revision=SELECTED_COMPARISON_SCHEMA,
|
|
).compatible
|
|
engine.dispose()
|