railiance-clock/tests/test_attribution.py
tegwick 3e537d117f Cover local acceptance gaps and reject nonfinite JSON exponents
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e6f0-a6f6-7b93-9124-55ef584930e2
2026-09-28 10:40:02 +02:00

59 lines
2.7 KiB
Python

from copy import deepcopy
import pytest
from railiance_clock import attribution
from railiance_clock.client import Clock, FileTrust
from railiance_clock.core import ClockError
def test_disabled_attribution_does_not_construct_clock(monkeypatch):
monkeypatch.delenv('TEST_CLOCK_TRUST', raising=False)
def unexpected(_):
pytest.fail('unconfigured attribution constructed a clock')
monkeypatch.setattr(attribution, '_clock', unexpected)
assert attribution.from_environment('TEST_CLOCK_TRUST') == {}
def test_recording_evidence_preserves_original_event(setup, monkeypatch):
path, _, timer, transport = setup
clock = Clock(FileTrust(path), timer=timer, transport=transport)
monkeypatch.setenv('TEST_CLOCK_TRUST', str(path))
monkeypatch.setattr(attribution, '_clock', lambda _: clock)
event = {'event_id': 'old-event', 'timestamp': '1999-01-01T10:00:00+01:00',
'clock_domain': 'old-boot', 'sequence': 7, 'predecessors': ['earlier']}
original = deepcopy(event)
evidence = attribution.from_environment('TEST_CLOCK_TRUST')
enriched = {**event, **evidence}
assert event == original
assert all(enriched[k] == v for k, v in original.items())
assert set(evidence) == {'railiance_time'}
sample = evidence['railiance_time']
assert sample['kind'] == 'recording_time' and sample['status'] == 'usable'
assert sample['lower_ns'] <= sample['upper_ns']
assert sample['sample_id'] and sample['authority_id'] == 'railiance01'
assert 'occurrence_time' not in sample
# A wall-clock label is retained as provenance, not recalibrated by this API.
assert enriched['timestamp'] == original['timestamp']
@pytest.mark.parametrize('error', [OSError('secret-path'), ClockError('private reason'),
KeyError('private field'), TypeError('private type')])
def test_unavailable_attribution_is_sanitized(monkeypatch, error):
monkeypatch.setenv('TEST_CLOCK_TRUST', '/unused')
def unavailable(_):
raise error
monkeypatch.setattr(attribution, '_clock', unavailable)
assert attribution.from_environment('TEST_CLOCK_TRUST') == {
'railiance_time': {'status': 'unavailable', 'kind': 'recording_time'}}
def test_expired_cached_clock_never_returns_old_evidence(setup, monkeypatch):
path, _, timer, transport = setup
clock = Clock(FileTrust(path), timer=timer, transport=transport)
monkeypatch.setenv('TEST_CLOCK_TRUST', str(path))
monkeypatch.setattr(attribution, '_clock', lambda _: clock)
assert attribution.from_environment('TEST_CLOCK_TRUST')['railiance_time']['status'] == 'usable'
timer.n = 61_000_000_000
assert attribution.from_environment('TEST_CLOCK_TRUST') == {
'railiance_time': {'status': 'unavailable', 'kind': 'recording_time'}}