atlas-iac/testing/tests/test_suite_recovery.py

245 lines
12 KiB
Python
Raw Normal View History

"""Fault injection exercises real orchestration without hosted model requests."""
import copy
import json
import threading
from pathlib import Path
import sys
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / 'scripts/ops'))
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / 'services/hermes/scripts'))
import suite_backends
import suite_hierarchical
import suite_multipass as workflow
import suite_recovery
from suite_contract import MODELS, Problem, preflight, validate_request, validate_result
from suite_profiles import PROFILE_FIELDS, profile_source, validate_profiles
from suite_recovery import Checkpoints
from suite_sizing import balanced_sizes
from suite_synthetic import fixture, score
from test_suite_multipass import natural, public, review, wire_value
from suite_capacity_fixture import fixture as realistic_fixture
class NoWait:
"""Cancellation remains testable without real retry sleeps."""
def is_set(self):
return False
def wait(self, _):
return False
def source(size=14, large=False):
raw, expected = realistic_fixture() if large else fixture(size)
raw['routing'] = {'allow_external': True, 'allowed_external_providers': ['claude']}
raw['execution'] = {'strategy': 'whole_suite', 'max_seconds': 7200, 'max_cost_usd': 60}
return validate_request(raw, ['claude']), expected
def oracle(monkeypatch, expected, failures=None):
"""Use an independent fixture map to check cross-batch control flow and validation."""
calls = []
failures = dict(failures or {})
def backend(request, cancel, *, invocation, progress=None, job_deadline=None):
stage = invocation['stage']
calls.append({'stage': stage, 'aliases': sorted(c['alias'] for c in request['cases']),
'seconds': request['execution']['max_seconds'], 'deadline': job_deadline,
'turns': invocation['max_turns'], 'source': copy.deepcopy(request['cases'])})
if failures.get(stage, 0):
failures[stage] -= 1
raise Problem('incomplete_generation', 502, final_event_subtype='success',
final_is_error=True, exit_code=1, assistant_api_error_seen=True,
structured_output_present=False, turns=1, max_turns=invocation['max_turns'],
cost_usd_estimate=0, usage={'input_tokens':0,'output_tokens':0})
if stage == 'implementation_profiles':
value = {'profiles': {}}
for c in request['cases']:
name = expected[c['alias']]
p = {k: None for k in PROFILE_FIELDS}
p.update(target=name, work='Implement '+name+' tests.', setup=name+' fixture',
stimulus=name+' stimulus', observations=name+' measurements',
machinery=name, evidence={'field':'success_criteria', 'quote':c['success_criteria'][:90]})
value['profiles'][c['alias']] = p
else:
parts = {}
for c in request['cases']:
parts.setdefault(expected[c['alias']], []).append(c['alias'])
decision = natural(request, list(parts.values()), list(parts))
if stage in ('proposal_a','proposal_b','profile_proposal_a','profile_proposal_b','profile_reconciliation'):
decision = public(decision)
if stage in ('large_family_review','decision_audit'):
decision = review(decision, decision)
value = wire_value(decision, invocation)
return value, {'model':MODELS['claude']['model'], 'cost_usd_estimate': 25.0,
'usage':{'input_tokens':100,'output_tokens':50}, 'turns':2, 'duration_api_ms':2,
'compaction':False, 'truncation':False, 'cli_diagnostics':{'exit_code':0}}
monkeypatch.setattr(suite_backends, 'claude_generate', backend)
return calls
def run(monkeypatch, *, mode='direct', size=14, large=False, failures=None):
request, expected = source(size, large)
calls = oracle(monkeypatch, expected, failures)
selected = {**preflight(request), 'execution_mode':mode}
updates = []
result, metadata = workflow.generate(request, selected, NoWait(), '192.168.22.8', updates.append,
credential_scope={'owner':'synthetic-test','providers':['claude']})
validate_result(result, request)
return request, expected, calls, result, metadata, updates
def test_proposal_b_retry_keeps_validated_a_and_same_source(monkeypatch):
request, expected, calls, result, meta, updates = run(monkeypatch, failures={'proposal_b':1})
assert [c['stage'] for c in calls].count('proposal_a') == 1
assert [c['stage'] for c in calls].count('proposal_b') == 2
attempts = [c for c in calls if c['stage']=='proposal_b']
assert attempts[0]['source'] == attempts[1]['source']
assert meta['retry_count']['proposal_b'] == 1
assert 'proposal_a' in meta['checkpointed_passes']
assert meta['cost_usd_estimate'] > 60 and meta['cost_guard_enforced'] is False
assert all(c['deadline']==calls[0]['deadline'] for c in calls)
assert score({'groups':meta['review_summary']['natural_families']}, expected)['false_merge_pairs']==0
def test_review_failure_does_not_regenerate_prior_passes(monkeypatch):
_, _, calls, _, meta, _ = run(monkeypatch, size=75, failures={'large_family_review':1})
for name in ('proposal_a','proposal_b','reconciliation'):
assert [c['stage'] for c in calls].count(name)==1
assert [c['stage'] for c in calls].count('large_family_review')==2
assert meta['retry_count']['large_family_review']==1
@pytest.mark.parametrize('mode', ['direct','hierarchical'])
def test_large_comparable_fixture_complete_and_globally_reconciled(monkeypatch, mode):
request, expected, calls, result, meta, updates = run(monkeypatch, mode=mode, large=True)
assert len(request['cases'])==363
assert max(len(g['members']) for g in result['groups'])<=5
assert len(result['groups'])==90 and meta['natural_family_count']==45
quality=score({'groups':meta['review_summary']['natural_families']}, expected)
assert quality['false_merge_pairs']==quality['missed_merge_pairs']==0
assert all(d['part_sizes']==balanced_sizes(d['natural_case_count']) for d in meta['review_summary']['capacity_divisions'])
if mode=='hierarchical':
assert meta['profile_batch_count']==16
for c in calls:
if c['stage'] in ('profile_proposal_a','profile_proposal_b','profile_reconciliation'):
assert len(c['aliases'])==363
originals={c['alias']:c for c in request['cases']}
reopened=[c for call in calls if call['stage']=='source_review' for c in call['source']]
assert {c['alias']:c for c in reopened}==originals
assert meta['cross_batch_review_count']==1
assert 'Implement ' not in json.dumps(updates)
def test_failed_direct_switches_only_after_bounded_recovery(monkeypatch):
_, _, calls, _, meta, _ = run(monkeypatch, failures={'proposal_b':3})
assert [c['stage'] for c in calls].count('proposal_a')==1
assert [c['stage'] for c in calls].count('proposal_b')==3
assert meta['execution_mode']=='hierarchical'
assert meta['strategy_events'][-1]['reason']=='pass_generation_retries_exhausted'
@pytest.mark.parametrize('code', ['provider_authentication','provider_forbidden','cancelled',
'invalid_review_evidence','worker_isolation_failed','job_time_budget_exhausted'])
def test_nonretriable_conditions_stop_without_fallback(monkeypatch, code):
request, _ = source()
seen=[]
def fail(*args, **kw):
seen.append(kw['invocation']['stage'])
raise Problem(code, 502)
monkeypatch.setattr(suite_backends,'claude_generate',fail)
with pytest.raises(Problem, match='^'+code+'$'):
workflow.generate(request, preflight(request), NoWait(),'192.168.22.8')
assert seen==['proposal_a']
def test_turn_recovery_grows_only_within_capacity(monkeypatch):
request, expected = source()
calls=oracle(monkeypatch,expected)
original=suite_backends.claude_generate
turns=[]
def backend(*args,**kw):
turns.append(kw['invocation']['max_turns'])
if len(turns)<3:
raise Problem('pass_turn_limit',502,cost_usd_estimate=0,turns=turns[-1],
max_turns=turns[-1],usage={'input_tokens':1,'output_tokens':1})
return original(*args,**kw)
monkeypatch.setattr(suite_backends,'claude_generate',backend)
workflow.generate(request,preflight(request),NoWait(),'192.168.22.8')
assert turns[:3]==[4,5,6]
def test_checkpoint_scope_hash_and_restart_behavior():
request,_=source()
call={'stage':'proposal_a','input':'synthetic','prior_hash':'a'}
store=Checkpoints(request,'claude',{'owner':'a'},float('inf'))
key=store.key(call);store.put(key,'proposal_a',{'groups':[]})
assert store.get(key,'proposal_a')=={'groups':[]}
assert store.key({**call,'prior_hash':'b'})!=key
assert Checkpoints(request,'claude',{'owner':'b'},float('inf')).key(call)!=key
assert Checkpoints(request,'claude',{'owner':'a'},float('inf')).get(key,'proposal_a') is None
store.clear();assert store.get(key,'proposal_a') is None
def test_cli_cost_guard_is_absent_and_legacy_request_cost_is_unenforced():
request,_=source()
request['execution']['max_cost_usd']=1e9
assert validate_request(request,['claude'])['execution']['max_cost_usd']==1e9
assert '--max-budget-usd' not in suite_backends.claude_command(MODELS['claude']['model'],60)
assert preflight(request)['cost_guard_enforced'] is False
def test_full_profile_set_fits_global_comparison_at_service_case_limit():
"""Bounded profiles keep every alias globally visible; no neighborhood shortcut."""
from suite_policy import invocation
request = {'campaign':'SYNTHETIC','suite':'CAPACITY','cases':[
{'alias':'CASE-'+str(i).zfill(48),'description':'Synthetic'} for i in range(400)]}
profiles = {c['alias']:{k:'x'*n for k,n in PROFILE_FIELDS.items()} for c in request['cases']}
compact = profile_source(request, profiles)
proposal = {'groups':[{'name':'x'*56,'members':[c['alias']]} for c in request['cases']]}
call = invocation('profile_reconciliation',compact,{'proposal_a':proposal,'proposal_b':proposal})
result = workflow.capacity(call,'claude',400)
assert result['max_turns'] >= 4 and result['context_reserved_tokens'] <= 1000000
assert len(call['schema']['properties']['assignments']['required']) == 400
def test_profile_evidence_and_exact_aliases_are_independently_validated():
request,expected=source()
c=request['cases'][0]
p={k:None for k in PROFILE_FIELDS}
p['evidence']={'field':'success_criteria','quote':c['success_criteria'][:90]}
subset={**request,'cases':[c]}
validate_profiles({'profiles':{c['alias']:p}},subset)
with pytest.raises(Problem,match='invalid_case_assignments'):
validate_profiles({'profiles':{'CASE-invented':p}},subset)
p['evidence']['quote']='unsupported secret instructions'
with pytest.raises(Problem,match='invalid_review_evidence'):
validate_profiles({'profiles':{c['alias']:p}},subset)
def test_checkpoint_hit_launches_no_new_model_call(monkeypatch):
request,expected=source()
calls=oracle(monkeypatch,expected)
worker=workflow.Workflow(request,preflight(request),NoWait(),'192.168.22.8',credential_scope='synthetic')
first=worker.call('proposal_a',request)
second=worker.call('proposal_a',request)
assert first==second and len(calls)==1
assert worker.safe_state()['checkpoint_reused']==['proposal_a']
assert len(worker.records)==1
def test_one_structured_assignment_repair_preserves_source(monkeypatch):
request,expected=source()
calls=oracle(monkeypatch,expected)
original=suite_backends.claude_generate
def backend(*args,**kwargs):
value,metadata=original(*args,**kwargs)
if len(calls)==1:
value['assignments'].pop(next(iter(value['assignments'])))
return value,metadata
monkeypatch.setattr(suite_backends,'claude_generate',backend)
result,meta=workflow.generate(request,preflight(request),NoWait(),'192.168.22.8')
assert meta['retry_count']=={'proposal_a':1}
assert calls[0]['source']==calls[1]['source']
validate_result(result,request)