62 lines
2.6 KiB
Python
62 lines
2.6 KiB
Python
|
|
"""The NK-WP-0056 exercises as contract tests (NK-WP-0058-T02): rows E2, E3 and E6 of the contract table.
|
||
|
|
|
||
|
|
T15: the executor's audit sender against audit-core's real ingestion and sender scope.
|
||
|
|
T19: the executor's KeyCape client and approval-engine carrier against approval-engine's real source and the KeyCape
|
||
|
|
binary from the pinned image (extracted by digest, no docker). Both use synthetic credentials and leave nothing
|
||
|
|
behind; locally the sibling checkouts, in CI the fetched owners. A missing sibling skips, which fails run.sh.
|
||
|
|
"""
|
||
|
|
import json
|
||
|
|
import re
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
REPO = Path(__file__).resolve().parents[3]
|
||
|
|
SIBLINGS = REPO.parent
|
||
|
|
EXECUTOR = REPO / 'bounded-executor'
|
||
|
|
|
||
|
|
|
||
|
|
def need(*owners):
|
||
|
|
missing = [o for o in owners if not (SIBLINGS / o).is_dir()]
|
||
|
|
if missing:
|
||
|
|
pytest.skip('owner checkout missing: ' + ', '.join(missing))
|
||
|
|
|
||
|
|
|
||
|
|
def run(argv):
|
||
|
|
return subprocess.run([sys.executable, *map(str, argv)], capture_output=True, text=True, timeout=600)
|
||
|
|
|
||
|
|
|
||
|
|
def test_t15_audit_sender_against_audit_core(tmp_path):
|
||
|
|
need('audit-core')
|
||
|
|
receipt = tmp_path / 't15.json'
|
||
|
|
done = run([EXECUTOR / 'exercise_audit_sender.py', '--receipt', receipt, '--audit-core-source',
|
||
|
|
SIBLINGS / 'audit-core'])
|
||
|
|
assert done.returncode == 0, done.stderr[-400:]
|
||
|
|
checks = json.loads(receipt.read_text())['checks']
|
||
|
|
assert checks and all(v is True for v in checks.values()), checks
|
||
|
|
|
||
|
|
|
||
|
|
def keycape_image():
|
||
|
|
"""The pinned image the exercise names (KEYCAPE_IMAGE), read from its source without importing it."""
|
||
|
|
text = (EXECUTOR / 'exercise_approval_identity.py').read_text()
|
||
|
|
parts = re.search(r'KEYCAPE_IMAGE = \("([^"]+)"\s*"([^"]+)"\)', text)
|
||
|
|
return parts.group(1) + parts.group(2)
|
||
|
|
|
||
|
|
|
||
|
|
def test_t19_keycape_client_and_approval_engine(tmp_path):
|
||
|
|
need('approval-engine', 'key-cape')
|
||
|
|
binary = tmp_path / 'keycape'
|
||
|
|
extracted = run([REPO / 'tools/contract-tests/oci_extract.py', '--image', keycape_image(), '--file', 'keycape',
|
||
|
|
'--out', binary])
|
||
|
|
assert extracted.returncode == 0, extracted.stdout
|
||
|
|
receipt = tmp_path / 't19.json'
|
||
|
|
done = run([EXECUTOR / 'exercise_approval_identity.py', '--receipt', receipt, '--keycape-binary', binary,
|
||
|
|
'--keycape-source', SIBLINGS / 'key-cape', '--approval-engine-source', SIBLINGS / 'approval-engine',
|
||
|
|
'--trace'])
|
||
|
|
assert done.returncode == 0, done.stderr[-400:]
|
||
|
|
r = json.loads(receipt.read_text())
|
||
|
|
assert r['status'] == 'passed' and r['keycape_runtime'] == 'binary from the pinned image'
|
||
|
|
assert r['checks'] and all(v is True for v in r['checks'].values()), r['checks']
|