Publish curated ITWorx-ModelForge source from 990401737f96c8d46a9f7b0d84994516cadcb6a0

This commit is contained in:
Public Source Publisher committed 2026-09-30 09:23:17 +00:00
1 parent 7082ab955a
commit 848f0d8f8a
434 files changed
+67298 -4315

No files matched your search

+230 -2
View File
@@ -6,13 +6,15 @@ import base64
import hashlib
import inspect
import json
import os
import stat
import uuid
from datetime import UTC, datetime, timedelta
from pathlib import Path
from typing import Any
import pytest
from sqlalchemy import create_engine, func, select
from sqlalchemy import create_engine, event, func, select
from sqlalchemy.orm import Session
from modelforge_api.domain.recovery import (
@@ -45,6 +47,8 @@ from modelforge_api.persistence.models import (
ModelRevision,
RecoveryAssetRecord,
RecoveryPolicyRevision,
RestoreOperation,
RestorePlan,
StorageRoot,
UpstreamSnapshot,
)
@@ -328,6 +332,7 @@ def seed_backup(
encrypted: bool = False,
payload: bytes = b"PGDMP-fake-custom-dump-payload",
milestone: str | None = None,
legal_hold: bool = False,
) -> tuple[RecoveryService, BackupSet]:
"""Create a VERIFIED-shaped backup on disk without invoking PostgreSQL tooling."""
@@ -403,6 +408,7 @@ def seed_backup(
encryption_key_id="modelforge-backup-key-1" if encrypted else None,
verification_details={},
milestone=milestone,
legal_hold=legal_hold,
reason="unit test fixture",
created_by="test",
started_at=datetime.now(UTC),
@@ -554,6 +560,50 @@ def test_an_encrypted_backup_verified_with_the_wrong_key_fails_closed(
assert not any(path.name.startswith("database.dump.enc.verify-") for path in directory.iterdir())
def test_encrypted_verification_stages_only_on_restore_volume(
session: Session, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
subject, record = seed_backup(
session, tmp_path, backup_id="m15-read-only-source", encrypted=True
)
observed: list[Path] = []
def inspect_dump(path: Path) -> int:
observed.append(path)
assert path.parent == (tmp_path / "restore").resolve()
assert path.read_bytes() == b"PGDMP-fake-custom-dump-payload"
if os.name == "posix":
assert stat.S_IMODE(path.stat().st_mode) == 0o600
return 1
monkeypatch.setattr(subject.engine, "list_dump_contents", inspect_dump)
result = subject.verify_backup(record.id)
assert result.state is BackupState.VERIFIED
assert len(observed) == 1
assert not observed[0].exists()
assert not list((tmp_path / "restore").iterdir())
assert sorted(path.name for path in (tmp_path / "backups" / "m15-read-only-source").iterdir()) == [
"database.dump.enc", "manifest.json"
]
def test_encrypted_verification_refuses_staging_inside_backup_root(
session: Session, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
subject, record = seed_backup(
session, tmp_path, backup_id="m15-overlapping-roots", encrypted=True
)
subject.settings = settings_for(tmp_path, backup_restore_root=tmp_path / "backups" / "staging")
monkeypatch.setattr(subject.engine, "list_dump_contents", lambda _payload: 1)
result = subject.verify_backup(record.id)
assert result.state is BackupState.FAILED
assert result.failure_code == RecoveryFailureCode.PATH_NOT_ALLOWED.value
assert not list((tmp_path / "backups" / "staging").iterdir())
def test_an_encrypted_backup_without_a_key_reports_key_unavailable(
session: Session, tmp_path: Path
) -> None:
@@ -605,6 +655,12 @@ def test_retention_never_expires_the_last_verified_backup(
record.expires_at = datetime.now(UTC) - timedelta(days=1)
session.commit()
preview = subject.preview_retention()
assert preview.retained_backup_ids == [record.backup_id]
assert preview.expiring_backup_ids == []
assert preview.decisions[0].reason == "MINIMUM_VERIFIED_BACKUPS"
assert subject.backup(record.id).state is BackupState.VERIFIED
result = subject.apply_retention()
assert result["expired"] == 0
assert subject.backup(record.id).state is BackupState.VERIFIED
@@ -637,6 +693,178 @@ def test_retention_expires_surplus_backups_but_keeps_the_policy_minimum(
assert states["m15-retention-0"] is BackupState.EXPIRED
def test_retention_preview_matches_apply_and_does_not_commit_or_write_audit(
session: Session, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
observed_at = datetime(2026, 9, 23, 12, 0, tzinfo=UTC)
records: list[BackupSet] = []
for backup_id, milestone, legal_hold in (
("m15-retention-expire", None, False),
("m15-retention-hold", None, True),
("m15-retention-milestone", "rc-baseline", False),
("m15-retention-minimum-a", None, False),
("m15-retention-minimum-b", None, False),
("m15-retention-created", None, False),
):
subject, record = seed_backup(
session,
tmp_path,
backup_id=backup_id,
milestone=milestone,
legal_hold=legal_hold,
)
records.append(record)
monkeypatch.setattr(subject.engine, "list_dump_contents", lambda _payload: 1)
for index, record in enumerate(records[:-1]):
subject.verify_backup(record.id)
record.verified_at = observed_at - timedelta(days=len(records) - index)
record.expires_at = observed_at - timedelta(days=1)
records[-1].expires_at = observed_at - timedelta(days=1)
session.commit()
states_before = {item.backup_id: item.state for item in records}
audit_count_before = session.scalar(select(func.count()).select_from(AuditEvent))
pending_policy = RecoveryPolicyRevision(
key="control-plane.preview-pending-test",
revision=1,
name="Pending preview policy",
asset_class="AUTHORITATIVE",
backup_method="POSTGRES_LOGICAL_CUSTOM",
retention_days=1,
minimum_verified_backups=1,
rpo_seconds=60,
rto_target_seconds=60,
restore_verification="FULL_RESTORE",
encryption_required=True,
external_dependency=False,
rehydration_allowed=False,
secret_class=None,
rationale="A pending row detects accidental autoflush in the read-only preview.",
active=True,
fingerprint="c" * 64,
created_by="test",
)
session.add(pending_policy)
commits: list[None] = []
def after_commit(_session: Session) -> None:
commits.append(None)
event.listen(session, "after_commit", after_commit)
try:
preview = subject.preview_retention(observed_at)
finally:
event.remove(session, "after_commit", after_commit)
assert preview.observed_at == observed_at
assert preview.minimum_verified_backups == 2
assert preview.retained_backup_ids == [
"m15-retention-hold",
"m15-retention-milestone",
"m15-retention-minimum-a",
"m15-retention-minimum-b",
]
assert preview.expiring_backup_ids == ["m15-retention-created", "m15-retention-expire"]
reasons = {item.backup_id: item.reason for item in preview.decisions}
assert reasons["m15-retention-hold"] == "LEGAL_HOLD"
assert reasons["m15-retention-milestone"] == "MILESTONE"
assert reasons["m15-retention-minimum-a"] == "MINIMUM_VERIFIED_BACKUPS"
assert {item.backup_id: item.state for item in records} == states_before
assert pending_policy in session.new
session.expunge(pending_policy)
assert session.scalar(select(func.count()).select_from(AuditEvent)) == audit_count_before
assert commits == []
assert not session.new and not session.dirty and not session.deleted
applied = subject.apply_retention(observed_at)
assert applied == {"expired": 2, "protected": 4, "skipped_active_restore": 0}
expired = session.scalars(
select(AuditEvent).where(AuditEvent.action == "BACKUP_EXPIRED")
)
assert {item.details["backup_id"] for item in expired} == set(preview.expiring_backup_ids)
assert {
item.backup_id for item in records if item.state == BackupState.EXPIRED.value
} == set(preview.expiring_backup_ids)
def test_retention_preview_reports_active_restore_and_apply_skips_without_policy_seeding(
session: Session, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
subject, record = seed_backup(session, tmp_path, backup_id="m15-retention-active")
monkeypatch.setattr(subject.engine, "list_dump_contents", lambda _payload: 1)
subject.verify_backup(record.id)
record.expires_at = datetime.now(UTC) - timedelta(days=1)
plan = RestorePlan(
backup_set_id=record.id,
mode="VALIDATION",
state="PREFLIGHT_PASSED",
target_environment="ISOLATED",
target_label="active-retention-preview",
database_destination="postgresql+psycopg://modelforge:secret@postgres:5432/mf_restore",
artifact_strategy="NONE",
secret_strategy="MANUAL", # noqa: S106 - recovery strategy label is not a secret
node_strategy="NONE",
preflight={},
validation_requirements={},
fingerprint="a" * 64,
reason="active restore retention guard test",
created_by="test",
)
session.add(plan)
session.flush()
session.add(
RestoreOperation(
plan_id=plan.id,
backup_set_id=record.id,
state="RESTORING_DATABASE",
attempt=1,
idempotency_key="b" * 64,
preflight_result={},
phase_durations={},
source_fingerprint={},
restored_fingerprint={},
fingerprint_diff={},
validation_result={},
)
)
session.commit()
preview = subject.preview_retention()
assert preview.active_restore_in_progress is True
assert preview.retained_backup_ids == [record.backup_id]
assert preview.expiring_backup_ids == []
assert preview.decisions[0].reason == "ACTIVE_RESTORE_IN_PROGRESS"
policy = session.scalar(
select(RecoveryPolicyRevision).where(
RecoveryPolicyRevision.key == "control-plane.database",
RecoveryPolicyRevision.active.is_(True),
)
)
assert policy is not None
policy.active = False
session.commit()
with pytest.raises(RecoveryError) as error:
subject.preview_retention()
assert error.value.code == "recovery_policy_missing"
# Historically the active-restore guard returned before looking up or seeding a policy.
assert subject.apply_retention() == {
"expired": 0,
"protected": 1,
"skipped_active_restore": 1,
}
assert session.scalar(
select(func.count()).select_from(RecoveryPolicyRevision).where(
RecoveryPolicyRevision.key == "control-plane.database",
RecoveryPolicyRevision.active.is_(True),
)
) == 0
assert record.state == BackupState.VERIFIED.value
def test_milestone_and_legal_hold_backups_are_never_expired(
session: Session, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
@@ -1057,7 +1285,7 @@ def test_the_alembic_tree_is_found_from_the_repository_layout() -> None:
assert root is not None and (root / "versions").is_dir()
revisions = _known_alembic_revisions()
assert revisions[0] == "20260824_0001"
assert revisions[-1] == "20260830_0024"
assert revisions[-1] == "20260924_0039"
assert len(revisions) == len(set(revisions))