Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
74 lines
3.7 KiB
Python
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)
|