Publish curated ITWorx-ModelForge source from 990401737f96c8d46a9f7b0d84994516cadcb6a0
This commit is contained in:
1 parent
7082ab955a
commit
848f0d8f8a
434 files changed
+67298
-4315
No files matched your search
@@ -0,0 +1,101 @@
|
||||
# ruff: noqa: S106 - isolated synthetic persistence fixtures
|
||||
"""Secret history fingerprint and migration contracts without external credentials."""
|
||||
import copy
|
||||
import importlib.util
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from alembic.migration import MigrationContext
|
||||
from alembic.operations import Operations
|
||||
from sqlalchemy import create_engine, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from modelforge_api.persistence.models import Base, SecretSlotState, SecretSlotVersion
|
||||
from modelforge_api.services.audit import AuditWriter
|
||||
from modelforge_api.services.recovery_fingerprint import (
|
||||
SECRET_SCHEMA,
|
||||
SECRET_TABLES,
|
||||
FingerprintCompatibility,
|
||||
_without_creative,
|
||||
_without_lab_execution,
|
||||
_without_model_changes,
|
||||
_without_model_updates,
|
||||
_without_secrets,
|
||||
_without_selected_comparisons,
|
||||
audit_fingerprint_differences_are_compatible,
|
||||
fingerprint_compatibility,
|
||||
unclassified_tables,
|
||||
)
|
||||
from modelforge_api.services.recovery_fingerprint import (
|
||||
fingerprint_session as _current_fingerprint_session,
|
||||
)
|
||||
|
||||
|
||||
def fingerprint_session(session: Session):
|
||||
return _without_lab_execution(_without_model_changes(_current_fingerprint_session(session)))
|
||||
|
||||
|
||||
def test_secret_history_is_strict_except_verified_recovery_marker() -> None:
|
||||
engine = create_engine("sqlite://")
|
||||
Base.metadata.create_all(engine)
|
||||
with Session(engine) as session:
|
||||
assert not unclassified_tables()
|
||||
session.add(SecretSlotVersion(version=1, key_id="qualification", secret_ciphertext="opaque",
|
||||
secret_nonce="nonce", created_at=datetime.now(UTC)))
|
||||
session.commit()
|
||||
before = _without_creative(_without_model_updates(_without_selected_comparisons(fingerprint_session(session))))
|
||||
assert before["tables"]["platform_secret_versions"]["redacted_columns"] == ["secret_ciphertext", "secret_nonce"]
|
||||
AuditWriter(session, "operator", "qualification").write("RECOVERY_RECONCILIATION_COMPLETED", "restore", None, {"restored": True})
|
||||
session.commit()
|
||||
after = _without_creative(_without_model_updates(_without_selected_comparisons(fingerprint_session(session))))
|
||||
contract = fingerprint_compatibility(before, after, source_schema_revision=SECRET_SCHEMA)
|
||||
assert contract.mode == "ALERT_NOTIFICATION_UPGRADE|PORTFOLIO_UPGRADE|SECRET_STRICT"
|
||||
assert audit_fingerprint_differences_are_compatible(before, after, contract)
|
||||
unrelated_marker = FingerprintCompatibility(
|
||||
True,
|
||||
f"UNRELATED|{contract.mode}",
|
||||
contract.allow_audit_checkpoint_introduction,
|
||||
contract.reason,
|
||||
)
|
||||
assert not audit_fingerprint_differences_are_compatible(before, after, unrelated_marker)
|
||||
for table in SECRET_TABLES:
|
||||
altered = copy.deepcopy(after)
|
||||
altered["tables"][table]["digest"] = "0" * 64
|
||||
assert not audit_fingerprint_differences_are_compatible(before, altered, contract)
|
||||
engine.dispose()
|
||||
|
||||
|
||||
def test_prior_schema_requires_exact_empty_secret_introduction() -> None:
|
||||
engine = create_engine("sqlite://")
|
||||
Base.metadata.create_all(engine)
|
||||
with Session(engine) as session:
|
||||
after = _without_creative(_without_model_updates(_without_selected_comparisons(fingerprint_session(session))))
|
||||
before = _without_secrets(after)
|
||||
contract = fingerprint_compatibility(before, after, source_schema_revision="20260908_0027")
|
||||
assert contract.compatible
|
||||
assert audit_fingerprint_differences_are_compatible(before, after, contract)
|
||||
for table in SECRET_TABLES:
|
||||
altered = copy.deepcopy(after)
|
||||
altered["tables"][table]["digest"] = "0" * 64
|
||||
assert not fingerprint_compatibility(before, altered, source_schema_revision="20260908_0027").compatible
|
||||
engine.dispose()
|
||||
|
||||
|
||||
def test_secret_migration_seed_empty_downgrade_and_history_refusal() -> None:
|
||||
path = Path(__file__).resolve().parents[1] / "alembic/versions/20260908_0028_platform_secret_slots.py"
|
||||
spec = importlib.util.spec_from_file_location("secret_migration", path)
|
||||
assert spec and spec.loader
|
||||
migration = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(migration)
|
||||
engine = create_engine("sqlite://")
|
||||
with engine.begin() as connection, Operations.context(MigrationContext.configure(connection)):
|
||||
migration.upgrade()
|
||||
assert connection.scalar(select(SecretSlotState.revision)) == 0
|
||||
migration.downgrade()
|
||||
migration.upgrade()
|
||||
connection.execute(SecretSlotVersion.__table__.insert().values(version=1, key_id="qualification",
|
||||
secret_ciphertext="opaque", secret_nonce="nonce", created_at=datetime.now(UTC)))
|
||||
with pytest.raises(RuntimeError, match="history exists"):
|
||||
migration.downgrade()
|
||||
engine.dispose()
|
||||
Reference in new issue
Block a user