Files
ModelForge-Public/backend/tests/test_recovery_audit_order_postgres.py
T

58 lines
2.3 KiB
Python

"""Real restored audit pagination must preserve numeric sequence ordering."""
from __future__ import annotations
import importlib
import os
from pathlib import Path
from sqlalchemy.orm import Session
from modelforge_api.services.audit import AuditWriter
from modelforge_api.services.recovery import RecoveryService
from modelforge_api.services.recovery_postgres import parse_target
from modelforge_api.settings import Settings
from tests.test_managed_identities_postgres import (
IdentityDatabase,
ManagedPostgresTools,
identity_database,
)
__all__ = ["identity_database"]
def test_restored_audit_numeric_order_crosses_page_boundary(
identity_database: IdentityDatabase, tmp_path: Path,
) -> None:
database = identity_database
importlib.import_module("alembic.command").upgrade(database.migration(), "head")
event_count = 512 # Production iteration reads 500 rows per page.
with Session(database.runtime) as session:
writer = AuditWriter(session, "operator", "audit-pagination-qualification")
expected_ids = []
for ordinal in range(1, event_count + 1):
event = writer.write(
"qualification.audit_pagination", "recovery", None,
{"ordinal": ordinal, "source": "isolated regression fixture"},
)
assert event.sequence == ordinal
expected_ids.append(str(event.id))
session.commit()
archive = tmp_path / "audit-pagination.dump"
database.archive(archive)
database.archive(archive, restore=True)
target = parse_target(database.restored_owner.render_as_string(hide_password=False))
with Session(database.runtime) as session:
recovery = RecoveryService(session, Settings(_env_file=None, env="test"))
recovery.engine = ManagedPostgresTools(
base_environment=dict(os.environ), timeout_seconds=60,
)
events = list(recovery._restored_audit_events(target))
assert [event.sequence for event in events] == list(range(1, event_count + 1))
assert [event.id for event in events] == expected_ids
assert len({event.id for event in events}) == event_count
checkpoint = recovery._verify_restored_audit_chain(target)
assert checkpoint.event_count == checkpoint.last_sequence == event_count
assert checkpoint.last_event_hash == events[-1].event_hash