"""Offline adversarial evidence/transport/resume tests; no network or Laravel env.""" import copy import hashlib import importlib.util import json from pathlib import Path import sys import tempfile import threading import time import unittest from unittest.mock import patch SCRIPTS=Path(__file__).resolve().parents[2]/'scripts/node-onboarding' sys.path.insert(0,str(SCRIPTS)) from acceptance import audit,digest,snapshot,service_change,provider_state from ssh_pool import Pool,private_json,credentials import batch class EvidenceTests(unittest.TestCase): def fixture(self,count): nodes=[dict(id=i,type='anytls',tag='node-'+str(i),relay='relay.example.invalid',relay_port=47000+i,sni=f'n{i}.example.invalid',expected_exit=f'192.0.2.{i}',country='JP') for i in range(1,count+1)] report={'state':'live_verified','verified_at':1000,'results':[dict(tag=n['tag'],relay=n['relay'],relay_port=n['relay_port'],sni=n['sni'],exit_ip=n['expected_exit'],country=n['country'],live=True,strict_tls=True) for n in nodes]} qas={'captured_at':1000,'plan_sha256':'plan','users':{'new':dict(id=9,http_status=403,banned=True,excluded=True)}} return nodes,report,qas def check(self,nodes,report,qas,after=None,**bindings): raw=json.dumps(report).encode();qraw=json.dumps(qas).encode() binding=dict(plan_sha256='plan',snapshot_sha256=digest(snapshot(nodes)),report_sha256=hashlib.sha256(raw).hexdigest(),qa_rejections_sha256=hashlib.sha256(qraw).hexdigest(),verified_at=1000) binding.update(bindings) return audit(nodes,nodes if after is None else after,raw,qraw,binding,'plan',{'new':9},now=1100) def test_arbitrary_node_counts_and_reordering(self): for count in [1,2,7,23]: nodes,report,qas=self.fixture(count) self.assertEqual(self.check(nodes,report,qas,after=list(reversed(nodes)))['nodes'],count) def test_topology_change_including_old_node_is_blocked(self): nodes,r,q=self.fixture(7) for after in [nodes[:-1],nodes+self.fixture(8)[0][-1:],list(reversed(nodes[:-1]))]: with self.assertRaises(ValueError):self.check(nodes,r,q,after=after) altered=copy.deepcopy(nodes);altered[0]['expected_exit']='198.51.100.9' with self.assertRaises(ValueError):self.check(nodes,r,q,after=altered) def test_missing_extra_duplicate_or_insecure_results_fail(self): nodes,r,q=self.fixture(7) for results in [r['results'][:-1],r['results']+[r['results'][0]],r['results'][1:]+[r['results'][1]]]: with self.assertRaises(ValueError):self.check(nodes,dict(r,results=results),q) for field,value in [('exit_ip','198.51.100.1'),('country','US'),('strict_tls',False),('live',False),('sni','wrong.example.invalid')]: wrong=copy.deepcopy(r);wrong['results'][0][field]=value with self.assertRaises(ValueError):self.check(nodes,wrong,q) def test_qa_identity_status_revocation_and_hashes_are_bound(self): nodes,r,q=self.fixture(2) for field,value in [('id',10),('http_status',200),('banned',False),('excluded',False)]: wrong=copy.deepcopy(q);wrong['users']['new'][field]=value with self.assertRaises(ValueError):self.check(nodes,r,wrong) for field in ['snapshot_sha256','plan_sha256','report_sha256','qa_rejections_sha256']: with self.assertRaises(ValueError):self.check(nodes,r,q,**{field:'wrong'}) for stamp in [-1,1200,None,'1000']: with self.assertRaises(ValueError):self.check(nodes,dict(r,verified_at=stamp),q) with self.assertRaises(ValueError):self.check(nodes,r,dict(q,captured_at=stamp)) def test_provider_observations_are_exact_and_not_language_or_substring_dependent(self): node=dict(key='new',tls_domain='a.example.invalid',relay_host='relay.example.invalid',relay_port=47001,node_address='192.0.2.1',listen_port=24443) observed={'captured_at':1000,'dns':[{'type':'A','name':node['tls_domain'],'address':node['node_address'],'proxy':False}],'relays':[{'name':'dpl-new-anytls','host':node['relay_host'],'port':47001,'target':node['node_address'],'listen_port':24443,'proxy_protocol_in':False,'proxy_protocol_out':False}]} self.assertTrue(provider_state(observed,node,1100)['dns']) for section,field,value in [('dns','proxy',True),('dns','address','192.0.2.11'),('relays','proxy_protocol_in',True),('relays','target','192.0.2.11')]: wrong=copy.deepcopy(observed);wrong[section][0][field]=value with self.assertRaises(ValueError):provider_state(wrong,node,1100) self.assertEqual(provider_state(dict(observed,dns=[],relays=[]),node,1100),{'dns':[],'relays':[]}) with self.assertRaises(ValueError):provider_state(observed,node,2000) def test_registry_and_service_changes_do_not_use_pid_alone(self): for values in [[],[dict(self.fixture(1)[0][0],type='vless')],self.fixture(1)[0]*2]: with self.assertRaises(ValueError):snapshot(values) before=dict(unit_sha256='a',binary_sha256='b',config_sha256='c',listeners=['*:443'],active=True,pid=1,started='yesterday',restarts=0) self.assertEqual(service_change(before,before),'ready') self.assertEqual(service_change(before,dict(before,pid=2)),'investigate_restart') self.assertEqual(service_change(before,dict(before,config_sha256='changed')),'conflict') self.assertEqual(service_change(before,dict(before,active=False)),'conflict') self.assertEqual(service_change(before,dict(before,binary_sha256=None)),'unknown') class TransportTests(unittest.TestCase): def test_reuse_and_every_nonwhite_host_has_jump(self): calls=[] class Client: active=True def get_transport(self):return self def is_active(self):return self.active def close(self):self.active=False def factory(rid,spec,jump):calls.append((rid,jump));return Client() config={'hosts':{'white':{'role':'white_jump'},'panel':{},'node':{}}} pool=Pool(config,'white',factory) panel=pool.get('panel');self.assertIs(panel,pool.get('panel')) node=pool.get('node');self.assertIs(calls[1][1],calls[2][1]);self.assertIsNone(calls[0][1]);self.assertEqual(len(calls),3) panel.active=False with self.assertRaises(RuntimeError):pool.get('panel') self.assertEqual(len(calls),3) # Never automatically replay after disconnect. pool.close();self.assertFalse(node.active) def test_sessions_are_not_shared_unsafely_between_workers(self): barrier=threading.Barrier(2);made=[] class Client: def get_transport(self):return self def is_active(self):return True def close(self):pass pool=Pool({'hosts':{'w':{'role':'white_jump'},'n':{}}},'w',lambda *args:Client()) def worker(): n=pool.get('n');barrier.wait();made.append(n);self.assertIs(n,pool.get('n')) threads=[threading.Thread(target=worker) for _ in range(2)] for t in threads:t.start() for t in threads:t.join(timeout=5) self.assertEqual(len(made),2);self.assertIsNot(made[0],made[1]);pool.close() def test_existing_codocs_credentials_are_read_without_copy_or_rewrite(self): with tempfile.TemporaryDirectory() as d: p=Path(d)/'vps.md';body='# Fixture\n密码:test-only-phrase\n';p.write_text(body);p.chmod(0o600) self.assertEqual(credentials({'credential_ref':str(p),'credential_format':'codocs-password'}),{'password':'test-only-phrase'}) self.assertEqual(p.read_text(),body);self.assertEqual(len(list(Path(d).iterdir())),1) p.write_text(body+'密码:ambiguous\n') with self.assertRaises(ValueError):credentials({'credential_ref':str(p),'credential_format':'codocs-password'}) def test_private_config_and_explicit_jump_enforced(self): with self.assertRaises(ValueError):Pool({'hosts':{'n':{}}},'w') with self.assertRaises(ValueError):Pool({'hosts':{'w':{}}},'w') with tempfile.TemporaryDirectory() as d: p=Path(d)/'auth.json';p.write_text('{}');p.chmod(0o644) with self.assertRaises(ValueError):private_json(p) p.chmod(0o600);self.assertEqual(private_json(p),{}) link=Path(d)/'link';link.symlink_to(p) with self.assertRaises(ValueError):private_json(link) class ResumeTests(unittest.TestCase): def setUp(self): batch.STOP.clear();self.tmp=tempfile.TemporaryDirectory();self.root=Path(self.tmp.name) spec=importlib.util.spec_from_file_location('batch_fixtures',Path(__file__).with_name('test_batch.py'));m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m) fixture=m.BatchTests();fixture.setUp();self.fixture=fixture;self.plan=fixture.plan self.calls=[];self.generation='a';self.finished=False owner=self class Runner(batch.Coordinator): def call(self,n,phase,action): owner.calls.append((phase,action)) r=dict(key=n['key'],phase=phase,request_sha256='irrelevant-in-unit-fixture',status='waiting' if phase=='audit' and not owner.finished else 'ready',valid_until=time.time()+180) if phase=='preflight':r['resume_dependencies']={k:hashlib.sha256((owner.generation if k=='provision' else k).encode()).hexdigest() for k in ['stage','dns','provision','relay','verify']} return r self.Runner=Runner def tearDown(self):self.fixture.tearDown();self.tmp.cleanup();batch.STOP.clear() def run_batch(self):return self.Runner(self.plan,self.root/'ledger',jobs=1).run() def test_fresh_proofs_skip_only_completed_unchanged_phases(self): self.assertFalse(self.run_batch());self.calls.clear();self.finished=True self.assertTrue(self.run_batch());self.assertEqual(self.calls,[('preflight','probe'),('publish','probe'),('audit','probe')]) def test_dependency_change_rechecks_downstream_and_not_unrelated_stage(self): self.run_batch();self.calls.clear();self.generation='b';self.finished=True;self.run_batch() self.assertEqual([p for p,a in self.calls],['preflight','provision','relay','verify','publish','audit']) def test_expired_and_unknown_proofs_never_skip(self): self.run_batch();runner=self.Runner(self.plan,self.root/'ledger',jobs=1) with runner.ledger.db() as c:c.execute('UPDATE evidence SET expires=0 WHERE phase="dns"') runner.ledger.mark(self.plan['batch_id'],self.plan['nodes'][0]['key'],'stage','unknown') self.calls.clear();self.finished=True;self.run_batch() self.assertIn(('stage','probe'),self.calls);self.assertIn(('dns','probe'),self.calls) self.assertTrue((self.root/'ledger/events.jsonl').is_file()) class SiteAdapterTests(unittest.TestCase): def test_qa_export_binds_raw_bytes_and_latest_traffic_for_independent_review(self): from site_adapter import SiteAdapter with tempfile.TemporaryDirectory() as d: adapter=object.__new__(SiteAdapter);adapter.directory=Path(d);adapter.atomic_json=batch.atomic_json raw=b'{ "state": "live_verified", "qa_user_id": 9 }' latest=dict(node_online=True,u=12,d=34,manifest={'test_user_id':9}) adapter.qa_evidence(dict(key='new',request_sha256='request'),raw,latest) path=Path(d)/'new-evidence.json';value=json.loads(path.read_text()) self.assertEqual(value['report_sha256'],hashlib.sha256(raw).hexdigest()) self.assertEqual(value['panel'],latest);self.assertEqual(path.stat().st_mode & 0o077,0) def test_new_live_qa_exports_new_raw_report_after_transfer_not_prior_report(self): import io from site_adapter import SiteAdapter with tempfile.TemporaryDirectory() as d: adapter=object.__new__(SiteAdapter);adapter.directory=Path(d);adapter.atomic_json=batch.atomic_json ctx=dict(panel_vps='panel',gateway_vps='gateway',node_root='/node',ops_root='/ops',app_root='/app',node_backup_root='/backups',qa_root='/qa',client_binary='/client',subscription_url='https://sub.example.invalid') adapter.plan={'context':ctx};adapter.ctx=ctx raw=json.dumps(dict(state='live_verified',qa_user_id=9,verified_at=int(time.time()),results=[dict(tag='new',live=True,strict_tls=True,exit_ip='192.0.2.11',country='JP')])).encode() class Channel: def shutdown_write(self):pass def recv_exit_status(self):return 0 class In: channel=Channel() def write(self,data):pass class Out(io.BytesIO):channel=Channel() class Writable(io.BytesIO): def __init__(self,files,path):super().__init__();self.files,self.path=files,path def close(self):self.files[self.path]=self.getvalue();super().close() class Sftp: def __init__(self,files):self.files=files def __enter__(self):return self def __exit__(self,*args):pass def open(self,path,mode): if mode=='w':return Writable(self.files,path) if path not in self.files:raise FileNotFoundError(path) return io.BytesIO(self.files[path]) def chmod(self,*args):pass def posix_rename(self,old,new):self.files[new]=self.files.pop(old) state=dict(manifest={'test_user_id':9},node_online=True,groups=['2'],qa_banned=False,u=12,d=34) class Remote: def __init__(self,kind):self.kind=kind;self.files={} def open_sftp(self):return Sftp(self.files) def exec_command(self,cmd,timeout=0): if cmd.endswith(' && php'):return In(),Out(json.dumps(state).encode()),Out() if 'verify-node.py' in cmd:self.files['/qa/new/qa-report.json']=raw return In(),Out(b'{}'),Out() remotes={key:Remote(key) for key in ['panel','gateway','node']} remotes['panel'].files.update({'/backups/new/node-config.yml':b'fixture-config','/backups/new/node-secret.env':b'fixture-env','/backups/new/qa-private.json':b'{}'}) class Pool: def get(self,key):return remotes[key] adapter.pool=Pool() node=dict(key='new',request_sha256='request',formal_group_id=1,vps_id='node',socks_port=19011,expected_exit='192.0.2.11',country='JP') result=adapter.call(node,'verify','probe');self.assertEqual(result['status'],'ready') exported=json.loads((Path(d)/'new-evidence.json').read_text());self.assertEqual(exported['report_sha256'],hashlib.sha256(raw).hexdigest());self.assertEqual(exported['panel']['d'],34) self.assertEqual(remotes['panel'].files['/backups/new/qa-report.json'],raw) def test_preserved_service_review_binds_original_and_exact_observation(self): from site_adapter import SiteAdapter adapter=object.__new__(SiteAdapter);adapter.ctx={'preserved_service':dict(unit='XrayR',binary='/bin/xrayr',config='/etc/xrayr.yml',port=443)} current=dict(unit_sha256='u',binary_sha256='b',config_sha256='c',listeners=['*:443'],active=True,pid=1,started='a',restarts=0) files={};read=lambda client,path:files.get(path) def write(client,path,value):files[path]=value.encode() if isinstance(value,str) else value def execute(client,cmd):return json.dumps(current) if cmd.startswith('python3') else '' adapter.guard_service(None,'/backup',read,write,execute) original=copy.deepcopy(current);current.update(pid=2,started='b',restarts=1) with self.assertRaisesRegex(RuntimeError,'investigate_'):adapter.guard_service(None,'/backup',read,write,execute) files['/backup/preserved-service-review.json']=json.dumps(dict(before_sha256=digest(original),after_sha256=digest(current),reason='Independently reviewed lifecycle panic',evidence_sha256='e'*64)).encode() adapter.guard_service(None,'/backup',read,write,execute) current['config_sha256']='changed' with self.assertRaisesRegex(RuntimeError,'conflict'):adapter.guard_service(None,'/backup',read,write,execute) self.assertEqual(json.loads(files['/backup/preserved-service-original.json']),original) def test_generated_remote_python_and_group_independent_php_compile(self): import ast import subprocess import io from site_adapter import SiteAdapter tree=ast.parse((SCRIPTS/'site_adapter.py').read_text()) for method in [n for n in ast.walk(tree) if isinstance(n,ast.FunctionDef) and n.name in ('formal','guard_service','certificate_gate')]: for c in ast.walk(method): if isinstance(c,ast.Assign) and any(isinstance(t,ast.Name) and t.id=='script' for t in c.targets): program=eval(compile(ast.Expression(c.value),'script-builder','eval'),{'repr':repr,'spec':{},'ctx':{'subscription_url':'https://sub.example.invalid'},'value':{'token':'test-only'}}) compile(program,'remote-'+method.name,'exec') with tempfile.TemporaryDirectory() as d: a=object.__new__(SiteAdapter);a.plan={'context':dict(panel_vps='panel',gateway_vps='gateway',node_root='/node',ops_root='/ops',app_root='/app',batch_backup_root='/batch',node_backup_root='/backups',qa_root='/qa',gateway_containers=['gateway-a','gateway-b'])};a.ctx=a.plan['context'];a.directory=Path(d) php_sources=[];calls=[] class Channel: def shutdown_write(self):pass def recv_exit_status(self):return 0 class In: channel=Channel() def write(self,body):php_sources.append(body) class Out: channel=Channel() def read(self): body=php_sources[-1] if '$base=json_decode' in body:return b'true' return json.dumps({'manifest':{},'node_online':True,'groups':['7'],'qa_banned':True,'u':1,'d':1}).encode() class DockerOut: channel=Channel() def read(self):return json.dumps([dict(Name='/gateway-a',Id='id-a',State={'StartedAt':'then'},RestartCount=0)]).encode() class Sftp: def __enter__(self):return self def __exit__(self,*args):pass def open(self,path,mode):return io.BytesIO(json.dumps({'/gateway-a':{'id':'id-a','started':'then','restarts':0}}).encode()) class Remote: def exec_command(self,cmd,timeout=0): calls.append(cmd) if cmd.startswith('docker inspect'): if cmd!='docker inspect gateway-a gateway-b':raise RuntimeError('Invalid gateway inventory command') return In(),DockerOut(),io.BytesIO() return In(),Out(),io.BytesIO() def open_sftp(self):return Sftp() class Pool: def get(self,rid):return Remote() a.pool=Pool();a.guard_service=lambda *args:None;a.formal=lambda *args:None n=dict(key='sg-new',request_sha256='a'*64,formal_group_id=7,vps_id='node') result=a.call(n,'audit','probe');self.assertEqual(result['status'],'ready');self.assertGreaterEqual(len(php_sources),2) for php in php_sources: result=subprocess.run(['php','-l'],input=php,text=True,capture_output=True) self.assertEqual(result.returncode,0,result.stderr) def test_pool_real_connect_interface_keeps_strict_keys_and_jump_sock(self): import types recorded=[] class FakeClient: def load_host_keys(self,path):recorded.append(('keys',path)) def set_missing_host_key_policy(self,p):recorded.append(('reject',p)) def get_host_keys(self):return self def add(self,*args):recorded.append(('approved-key',args)) def connect(self,host,**kw):recorded.append(('connect',host,kw)) def get_transport(self):return self def is_active(self):return True def open_channel(self,kind,target,origin):recorded.append(('jump',kind,target));return 'through-white' def close(self):pass class Key: def asbytes(self):return b'approved-public-key-fixture' def get_name(self):return 'ssh-ed25519' class Keys: def __init__(self,path):pass def lookup(self,name):return {'ssh-ed25519':Key()} module=types.SimpleNamespace(SSHClient=FakeClient,RejectPolicy=lambda:'reject-unknown',HostKeys=Keys) pin='SHA256:'+__import__('base64').b64encode(hashlib.sha256(Key().asbytes()).digest()).decode().rstrip('=') with tempfile.TemporaryDirectory() as d,patch.dict(sys.modules,{'paramiko':module}): keys=Path(d)/'known_hosts';keys.write_text('public fixture');keys.chmod(0o600) credentials=Path(d)/'credentials.json';credentials.write_text(json.dumps({'password':'test-only-fixture'}));credentials.chmod(0o600) hosts={'w':dict(role='white_jump',host='192.0.2.1',username='root',credential_ref=str(credentials)),'n':dict(host='192.0.2.2',username='root',credential_ref=str(credentials))} for host in hosts.values():host['host_key_sha256']=pin p=Pool(dict(hosts=hosts,known_hosts=str(keys)),'w');p.get('n');p.get('n');p.close() before_connects=len([x for x in recorded if x[0]=='connect']) hosts['w']['host_key_sha256']='SHA256:'+'b'*43 blocked=Pool(dict(hosts=hosts,known_hosts=str(keys)),'w') with self.assertRaises(ValueError):blocked.get('n') self.assertEqual(len([x for x in recorded if x[0]=='connect']),before_connects) blocked.close() connections=[x for x in recorded if x[0]=='connect'];self.assertEqual(len(connections),2);self.assertIsNone(connections[0][2]['sock']);self.assertEqual(connections[1][2]['sock'],'through-white') self.assertEqual(len([x for x in recorded if x[0]=='reject']),2) for _,_,kw in connections:self.assertFalse(kw['allow_agent']);self.assertFalse(kw['look_for_keys']) def test_configure_is_local_only_and_pins_code_context_and_interpreter(self): import types spec=importlib.util.spec_from_file_location('configure_site',SCRIPTS/'configure-site.py');module=importlib.util.module_from_spec(spec);spec.loader.exec_module(module) with tempfile.TemporaryDirectory() as d: root=Path(d);ssh=root/'ssh.json';registry=root/'exits.json';(root/'known_hosts').write_text('public fixture');(root/'known_hosts').chmod(0o600) hosts={'VPS-001':dict(role='white_jump',host='192.0.2.1',username='root'),'VPS-002':dict(host='192.0.2.2',username='root'),'VPS-003':dict(host='192.0.2.3',username='root'),'VPS-011':dict(host='192.0.2.11',username='root')} for host in hosts.values():host['host_key_sha256']='SHA256:'+'a'*43 ssh.write_text(json.dumps({'hosts':hosts,'known_hosts':str(root/'known_hosts')}));ssh.chmod(0o600);registry.write_text('{}');registry.chmod(0o600) fixture_spec=importlib.util.spec_from_file_location('base_fixture',Path(__file__).with_name('test_batch.py'));f=importlib.util.module_from_spec(fixture_spec);fixture_spec.loader.exec_module(f) original=f.BatchTests();original.setUp() try: base=original.plan;node=base['nodes'][0];node['node_address']='192.0.2.11';node['expected_exit']='192.0.2.11';base['context'].update(jump_vps='VPS-001',panel_vps='VPS-002',gateway_vps='VPS-003');registry.write_text(json.dumps({node['tls_domain']:{'expected_exit':node['expected_exit'],'country':node['country']}})) site=dict(client_sha256='d'*64,ops_root='/ops',node_root='/node',batch_backup_root='/backup/batch',node_backup_root='/backup/nodes',qa_root='/qa/batch',provider_snapshot=str(root/'provider.json'),exit_registry=str(registry),ssh_config=str(ssh),preserved_service=dict(unit='XrayR',binary='/bin/xrayr',config='/etc/xrayr.yml',port=443),formal_socks_port=19999,gateway_containers=['gateway-a']) with patch.dict(sys.modules,{'paramiko':types.SimpleNamespace(__version__='5.0.0')}): plan=module.configure(base,site);self.assertEqual(plan['runtime']['kind'],'ssh-site-v1');self.assertFalse((root/'ledger').exists()) runner=batch.Coordinator(plan,root/'ledger',jobs=1);runner.runtime.close();runner.check_runtime() ssh.write_text(ssh.read_text()+'\n') with self.assertRaises(ValueError):runner.check_runtime() finally:original.tearDown() class PackagingTests(unittest.TestCase): def test_committed_flat_snapshot_preserves_worktree_index_and_base(self): import subprocess spec=importlib.util.spec_from_file_location('bundle_ops',SCRIPTS/'bundle-ops.py');module=importlib.util.module_from_spec(spec);spec.loader.exec_module(module) with tempfile.TemporaryDirectory() as d: root=Path(d);repo=root/'repo';repo.mkdir() def git(*args):return subprocess.check_output(['git','-C',str(repo),*args],stderr=subprocess.DEVNULL) git('init');git('config','user.name','Offline Test');git('config','user.email','test@example.invalid');git('config','commit.gpgsign','false') (repo/'base-only.txt').write_text('preserved operations base');git('add','.');git('commit','-m','base');base=git('rev-parse','HEAD').decode().strip() source_dir=repo/'scripts/node-onboarding';source_dir.mkdir(parents=True) for name in module.FILES:(source_dir/name).write_text('committed '+name) git('add','.');git('commit','-m','source');source=git('rev-parse','HEAD').decode().strip() (repo/'base-only.txt').write_text('unrelated user modification');(repo/'unrelated.txt').write_text('staged unrelated');git('add','unrelated.txt') index_before=git('diff','--cached','--binary');status_before=git('status','--porcelain') output=root/'operations.bundle';result=module.build(repo,source,base,'codex/offline-ops',output) self.assertTrue(output.exists());self.assertEqual(git('diff','--cached','--binary'),index_before);self.assertEqual(git('status','--porcelain'),status_before) self.assertEqual(git('show',result['commit']+':panel-acceptance.php'),b'committed panel-acceptance.php') self.assertEqual(git('show',result['commit']+':base-only.txt'),b'preserved operations base') self.assertEqual(git('rev-parse','HEAD').decode().strip(),source) git('bundle','verify',str(output)) with self.assertRaises(ValueError):module.build(repo,source,base,'codex/offline-ops',root/'second.bundle') advanced=module.build(repo,source,result['commit'],'codex/offline-ops',root/'advanced.bundle',advance=True) self.assertEqual(git('rev-parse',advanced['commit']+'^').decode().strip(),result['commit']) with self.assertRaises(ValueError):module.build(repo,source,base,'codex/offline-ops',root/'stale.bundle',advance=True) def test_event_stream_preserves_final_result_and_avoids_status_polling(self): import subprocess spec=importlib.util.spec_from_file_location('event_fixture',Path(__file__).with_name('test_batch.py'));f=importlib.util.module_from_spec(spec);spec.loader.exec_module(f) test=f.BatchTests();test.setUp() try: result=subprocess.run(test.argv()+['--events'],capture_output=True,text=True,timeout=30) self.assertEqual(result.returncode,0,result.stderr) lines=[json.loads(x) for x in result.stdout.splitlines()] self.assertTrue(lines[-1]['complete']);self.assertTrue(any(x.get('phase')=='provision' for x in lines[:-1])) for x in lines[:-1]:self.assertEqual(set(x),{'batch','node','phase','status','time'}) finally:test.tearDown() if __name__=='__main__':unittest.main()