autonomy-smoke-tests pr82 PASS evidence_sha256=c16c68f86ee0c4e8cfd0af3f76078be45441ee151395fbde5800145c08e189b5
autonomy-unit-tests pr82 FAIL evidence_sha256=44994ff4cfe08df298fe59f790f3f98df7aa29e4d239ecd185b3143818c540cd
campaign-approval-gate pr82 PASS evidence_sha256=0616d6aa11496391686dcbd658123e51d8d057e1f02661af7ef8512554e404d8
git-diff-check pr82 PASS evidence_sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
py-compile pr82 PASS evidence_sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
reconciliation-contract pr82 PASS evidence_sha256=a0d5c1849c776f73fa64b02300e10c193241c0f9460e6ad4e69d73ae720de90b
release-state-machine pr82 PASS evidence_sha256=1d3314562a9345a9f75b1adf32d61168822c00d316f7db85833230bba023e448
secret-scan pr82 PASS evidence_sha256=9ca1f810bf76589206704716c4f3701a6b6aca1066b1d0c24b91d5be008f52a2
signer-validator-contract pr82 PASS evidence_sha256=775b7aa27d0c17f48b3feff20c836f14b6ed8ebcb90ec7e0b76d2a13c579268a
65 lines
2.6 KiB
Python
65 lines
2.6 KiB
Python
"""
|
|
Contract: release_approval_reopen must perform an atomic saga CAS that is
|
|
pinned to the saga's current revision.
|
|
|
|
Guards against the defect where `service.sagas.compare_and_set(...)` was called
|
|
without the required keyword-only `expected_revision` argument, which raised
|
|
TypeError -> APPROVAL_REOPEN_SAGA_CAS_FAILED (HTTP 409) and blocked the reopen.
|
|
"""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
APP = Path(__file__).resolve().parents[1] / "active-runtime" / "app" / "release_approval_reopen.py"
|
|
MODULE = APP.name
|
|
|
|
CAS_CALL = re.compile(
|
|
r"service\.sagas\.compare_and_set\("
|
|
r"[^)]*?"
|
|
r"expected_revision\s*=\s*[^\s,]+"
|
|
r"[^)]*?\)",
|
|
re.S,
|
|
)
|
|
REVISION_SRC = re.compile(r"expected_revision\s*=\s*(?:saga\.get\(\s*[\"']revision[\"']\s*\)|saga\s*\.\s*revision)")
|
|
STATE_CAS = re.compile(r"expected_states\s*=\s*\{_state\(\s*[\"']APPROVED[\"']\s*\)\}")
|
|
TARGET_RFA = re.compile(r"target\s*=\s*_state\(\s*[\"']READY_FOR_APPROVAL[\"']\s*\)")
|
|
|
|
|
|
def _read():
|
|
if not APP.exists():
|
|
raise AssertionError(f"{MODULE} not found at {APP}")
|
|
return APP.read_text(encoding="utf-8")
|
|
|
|
|
|
def test_compare_and_set_call_requires_expected_revision():
|
|
src = _read()
|
|
# Exactly one compare_and_set call site in reopen module
|
|
calls = CAS_CALL.findall(src)
|
|
assert len(calls) == 1, f"expected exactly 1 compare_and_set call in {MODULE}, found {len(calls)}"
|
|
# The call must pass expected_revision (required keyword-only arg)
|
|
assert "expected_revision=" in calls[0], (
|
|
f"{MODULE} calls compare_and_set without expected_revision -> "
|
|
"TypeError -> APPROVAL_REOPEN_SAGA_CAS_FAILED"
|
|
)
|
|
# The expected_revision must be derived from the saga's current revision
|
|
assert REVISION_SRC.search(calls[0]), (
|
|
"expected_revision must be pinned to the saga current revision "
|
|
"(e.g. saga.get('revision') or saga.revision) for a true atomic CAS"
|
|
)
|
|
|
|
|
|
def test_cas_semantics_not_weakened():
|
|
src = _read()
|
|
# Still transitions APPROVED -> READY_FOR_APPROVAL (no weakening of state CAS)
|
|
assert STATE_CAS.search(src), "expected_states={_state('APPROVED')} must be preserved"
|
|
assert TARGET_RFA.search(src), "target=_state('READY_FOR_APPROVAL') must be preserved"
|
|
|
|
|
|
def test_reopen_still_binds_all_fingerprints():
|
|
src = _read()
|
|
# The expected_* sha256 bindings must still be enforced by ReopenRequest
|
|
for field in ("expected_approval_fingerprint", "expected_source_commit",
|
|
"expected_tree_oid", "expected_artifact_sha256",
|
|
"expected_manifest_sha256", "expected_release_plan_sha256",
|
|
"expected_policy_sha256"):
|
|
assert field in src, f"{MODULE} no longer enforces {field}"
|