from __future__ import annotations import importlib.util import sys import unittest from pathlib import Path SCRIPT_PATH = Path(__file__).with_name("serve-synthetic-rollback-executor.py") SPEC = importlib.util.spec_from_file_location( "serve_synthetic_rollback_executor", SCRIPT_PATH ) assert SPEC is not None and SPEC.loader is not None MODULE = importlib.util.module_from_spec(SPEC) sys.modules[SPEC.name] = MODULE SPEC.loader.exec_module(MODULE) def _request() -> dict[str, object]: return { "schema_version": "oas.rollback-executor.v1", "idempotency_key": "10000000-0000-0000-0000-000000000001", "approval_event_id": "20000000-0000-0000-0000-000000000001", "rollback_scope": "model", "target_kind": "model_change_gate", "target_id": "30000000-0000-0000-0000-000000000001", "subject_id": "candidate-v2", "rollback_target_id": "baseline-v1", "artifact_record_id": "40000000-0000-0000-0000-000000000001", "artifact_id": "rollback-model-v1", "artifact_sha256": "a" * 64, "artifact_provenance_uri": "repo://synthetic/g8/rollback", "authorization_evidence_refs": ["audit://synthetic/g8/approval"], } class SyntheticRollbackExecutorUnitTest(unittest.TestCase): def test_receipt_echoes_every_store_validated_binding(self) -> None: request = _request() receipt = MODULE.build_synthetic_receipt(request) for key in ( "idempotency_key", "rollback_scope", "target_kind", "target_id", "artifact_record_id", "artifact_sha256", ): self.assertEqual(receipt[key], request[key]) self.assertEqual(receipt["status"], "executed") self.assertEqual(len(receipt["evidence_refs"]), 1) def test_receipt_is_idempotent_for_same_command(self) -> None: request = _request() self.assertEqual( MODULE.build_synthetic_receipt(request), MODULE.build_synthetic_receipt(dict(request)), ) def test_invalid_artifact_hash_fails_closed(self) -> None: request = _request() request["artifact_sha256"] = "not-a-hash" with self.assertRaisesRegex(MODULE.HarnessError, "artifact sha256"): MODULE.build_synthetic_receipt(request) if __name__ == "__main__": unittest.main()