activity-core/tests/test_custodian_capture.py
tegwick 9ef75e0e18
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Failing after 2m10s
feat: checkpoint standalone Custodian snapshot receiver
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
2026-10-19 17:56:32 +02:00

74 lines
3.7 KiB
Python

import base64
from datetime import datetime, timezone
import hashlib
import json
import httpx
import pytest
from activity_core.custodian_capture import receive, run_capture
@pytest.fixture
def capture_runtime(tmp_path, monkeypatch):
state, snapshots = tmp_path / 'state', tmp_path / 'snapshots'
state.mkdir(mode=0o700)
(state / 'inputs').mkdir()
snapshots.mkdir()
policy = state / 'policy.json'
policy.write_text(json.dumps({'schema': 'activity-core.custodian-input-policy.v1', 'repositories': ['example'],
'max_snapshot_bytes': 1024, 'max_observation_age_seconds': 7200, 'max_future_skew_seconds': 300,
'expected_hub_instance': 'railiance01'}))
for name, value in {'STATE_ROOT': state, 'SNAPSHOT_WRITE_ROOT': snapshots, 'INPUT_POLICY': policy,
'PUBLISHER_URL': 'http://publisher.invalid'}.items():
monkeypatch.setenv('ACTIVITY_CORE_CUSTODIAN_' + name, str(value))
manifest = {'schema': 'repo-manager.fleet-input.v1', 'repositories': [{'slug': 'example', 'commit': 'a' * 40,
'files': [{'path': 'workplans/task.md', 'bytes': 4, 'sha256': hashlib.sha256(b'task').hexdigest()}]}]}
receipts = [{'schema': 'repo-manager.freshness-receipt.v1', 'repo_slug': 'example', 'outcome': 'applied',
'finished_at': datetime.now(timezone.utc).isoformat(),
'hub': {'verified_primary': True, 'instance_role': 'primary', 'instance_label': 'railiance01'},
**{key: 'a' * 40 for key in ('forge_commit', 'expected_commit', 'derived_commit', 'projected_commit')}}]
m, r = json.dumps(manifest), json.dumps(receipts)
mh, rh = hashlib.sha256(m.encode()).hexdigest(), hashlib.sha256(r.encode()).hexdigest()
bundle = {'schema': 'repo-manager.custodian-capture.v1', 'manifest': m, 'receipts': r,
'manifest_sha256': mh, 'receipts_sha256': rh,
'snapshot_id': hashlib.sha256((mh + rh).encode()).hexdigest(),
'files': {'example/workplans/task.md': base64.b64encode(b'task').decode()}}
return state, snapshots, policy, bundle
def test_receiver_retains_before_selecting_and_identical_retry(capture_runtime):
state, snapshots, policy, bundle = capture_runtime
first = receive(bundle, state, snapshots, policy)
assert receive(bundle, state, snapshots, policy) == first
descriptor = json.loads((state / 'inputs/current.json').read_text())
assert descriptor['snapshot_id'] == bundle['snapshot_id']
assert (snapshots / bundle['snapshot_id'] / 'example/workplans/task.md').read_text() == 'task'
def test_failed_capture_does_not_advance_descriptor(capture_runtime):
state, snapshots, policy, bundle = capture_runtime
(state / 'inputs/current.json').write_text('unchanged')
bundle['files']['example/workplans/task.md'] = base64.b64encode(b'bad').decode()
with pytest.raises(ValueError):
receive(bundle, state, snapshots, policy)
assert (state / 'inputs/current.json').read_text() == 'unchanged'
assert not (snapshots / bundle['snapshot_id']).exists()
def test_fixed_endpoint_transport_sends_no_forge_credential(capture_runtime):
bundle = capture_runtime[3]
def handler(request):
assert request.method == 'POST'
assert request.url.path == '/ports/repositories/custodian-snapshot'
assert 'authorization' not in request.headers
return httpx.Response(200, json=bundle)
assert run_capture({}, transport=httpx.MockTransport(handler))['status'] == 'completed'
def test_transport_error_sanitized(capture_runtime):
def handler(request):
return httpx.Response(500, text='sensitive upstream details')
with pytest.raises(ValueError, match='bounded owner snapshot reception failed') as error:
run_capture({}, transport=httpx.MockTransport(handler))
assert 'sensitive' not in str(error.value)