Add versioned ephemeral custody lifecycle
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02669-87ee-7a31-b111-edc95a16e0fa
This commit is contained in:
parent
985cef2572
commit
30e6edc236
17 changed files with 2855 additions and 6 deletions
89
tests/test_wp0025_broker_readiness.py
Normal file
89
tests/test_wp0025_broker_readiness.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SCRIPTS = ROOT / "scripts"
|
||||
TESTS = ROOT / "tests"
|
||||
for path in (SCRIPTS, TESTS):
|
||||
if str(path) not in sys.path:
|
||||
sys.path.insert(0, str(path))
|
||||
|
||||
from test_custody_contract import projection_contract
|
||||
|
||||
SPEC = importlib.util.spec_from_file_location(
|
||||
"wp0025_broker_readiness", SCRIPTS / "wp0025-broker-readiness.py"
|
||||
)
|
||||
assert SPEC and SPEC.loader
|
||||
module = importlib.util.module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(module)
|
||||
|
||||
|
||||
class BrokerReadinessTests(unittest.TestCase):
|
||||
def test_show_is_direct_and_authorizes_no_live_mutation(self) -> None:
|
||||
result = module.show(projection_contract())
|
||||
self.assertEqual("whitehat-security", result["owner"])
|
||||
self.assertIn("approve", result["approve_command"])
|
||||
self.assertFalse(result["live_mutation_authorized"])
|
||||
self.assertFalse(result["secret_values_observed"])
|
||||
|
||||
def test_adapter_verification_pins_revision_file_and_focused_test(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
adapter = root / module.DEFAULT_ADAPTER
|
||||
test = root / module.DEFAULT_TEST
|
||||
adapter.parent.mkdir(parents=True)
|
||||
test.parent.mkdir(parents=True)
|
||||
adapter.write_text("class PlatformCustodyBroker: pass\n", encoding="utf-8")
|
||||
test.write_text("def test_adapter(): assert True\n", encoding="utf-8")
|
||||
|
||||
def runner(command, **kwargs):
|
||||
if command[:2] == ["git", "rev-parse"]:
|
||||
return subprocess.CompletedProcess(command, 0, stdout="a" * 40 + "\n", stderr="")
|
||||
return subprocess.CompletedProcess(command, 0, stdout="1 passed\n", stderr="")
|
||||
|
||||
result = module.verify_adapter(root, runner=runner)
|
||||
self.assertTrue(result["passed"])
|
||||
self.assertEqual("a" * 40, result["adapter"]["revision"])
|
||||
self.assertEqual(64, len(result["adapter"]["sha256"]))
|
||||
self.assertTrue(result["adapter"]["tests_passed"])
|
||||
|
||||
def test_missing_adapter_fails_without_running_commands(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
result = module.verify_adapter(
|
||||
Path(directory),
|
||||
runner=lambda *args, **kwargs: self.fail("runner must not execute"),
|
||||
)
|
||||
self.assertFalse(result["passed"])
|
||||
self.assertFalse(result["secret_values_observed"])
|
||||
|
||||
def test_approval_round_trip_and_change_request(self) -> None:
|
||||
contract = projection_contract()
|
||||
verification = {
|
||||
"passed": True,
|
||||
"adapter": {
|
||||
"repo": "whitehat-security",
|
||||
"revision": "a" * 40,
|
||||
"path": str(module.DEFAULT_ADAPTER),
|
||||
"sha256": "b" * 64,
|
||||
"tests_passed": True,
|
||||
},
|
||||
"secret_values_observed": False,
|
||||
}
|
||||
receipt = module.build_approval(contract, "whitehat-owner", verification)
|
||||
self.assertEqual("approve", receipt["decision"])
|
||||
self.assertTrue(receipt["cleanup_request_supported"])
|
||||
change = module.build_change_request(contract, "whitehat-owner", "Bind cleanup acknowledgement.")
|
||||
self.assertEqual("request-changes", change["decision"])
|
||||
with self.assertRaises(module.ReadinessError):
|
||||
module.build_change_request(contract, "whitehat-owner", "")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue