Harden base progression and cleanup; validate finite physical resupply

This commit is contained in:
2026-09-19 10:39:39 +02:00
parent 40a474934c
commit 7c53b4bb81
377 changed files with 51882 additions and 92 deletions
+69
View File
@@ -0,0 +1,69 @@
"""Run the real archiver against synthetic sealed startup logs, without engines."""
from pathlib import Path
import json
import shutil
import subprocess
import sys
import tempfile
import unittest
ROOT=Path(__file__).resolve().parents[1]
sys.path.insert(0,str(ROOT/'tools'))
from native_provenance import snapshot,persist,bindings,seal_run
from test_vanilla_game_control import BASE
ORDINARY='''00 SCRIPT : Module: Game; defines: "PLATFORM_WINDOWS"
00 SCRIPT : ERR ORDINARY: header verified project=core systems=MissionSystems
00 SCRIPT : Rereintroduced [mission]: phase 0 -> 1
00 SCRIPT : ERR ORDINARY: local participant verified project=core phase=prison
'''
class ArchiveControl(unittest.TestCase):
def archive(self,project,result,control=None,cleanup=True,content=None):
tmp=tempfile.TemporaryDirectory(prefix='erri-archive-control-test-');self.addCleanup(tmp.cleanup)
root=Path(tmp.name);(root/'addons/core').mkdir(parents=True)
(root/'addons/core/addon.gproj').write_text('Synthetic fixture source, not a native project')
tools=root/'tools';tools.mkdir()
for name in ('archive_native.py','native_report.py','source_manifest.py','native_provenance.py','headless_game.py'):
shutil.copyfile(ROOT/'tools'/name,tools/name)
session=root/'session';session.mkdir()
(session/'console.log').write_text(content if content is not None else BASE if project=='vanilla-control' else ORDINARY)
captured=snapshot(root,['synthetic-archive-test-no-engine']);persist(session,captured)
data={**bindings(captured),'started_unix':json.loads(captured[1])['captured_unix'],**seal_run(root,session,captured),'project':project,'result':result,'cleanup_confirmed':cleanup}
if control is not None:data['control_only']=control
(session/'runner.json').write_text(json.dumps(data))
# Deliberately false saved status; actual archiver must recompute sealed log.
(session/'game-startup-report.json').write_text('{"ready":true,"failed":false}')
command=[sys.executable,str(tools/'archive_native.py'),str(session),'control']
done=subprocess.run(command,text=True,capture_output=True)
dest=root/'docs/evidence/control'
self.assertTrue(dest.exists(),done.stderr)
self.assertEqual((dest/'console.log.txt').read_bytes(),(session/'console.log').read_bytes())
return done,json.loads((dest/'report.json').read_text()),command,dest
def test_clean_control_gets_own_result_and_no_successor_qualification(self):
result,report,command,dest=self.archive('vanilla-control','vanilla-control-started',True)
self.assertEqual(result.returncode,0,result.stderr)
self.assertTrue(report['control_metadata_consistent']);self.assertTrue(report['control_only'])
self.assertFalse(report['normal_mission_ready']);self.assertFalse(report['scenario_header_verified'])
self.assertIn('no successor',report['qualification'])
before=(dest/'report.json').read_bytes()
duplicate=subprocess.run(command,capture_output=True,text=True)
self.assertNotEqual(duplicate.returncode,0);self.assertEqual((dest/'report.json').read_bytes(),before)
def test_control_rejects_ordinary_result_or_inconsistent_flag(self):
for result,flag in [('game-started',True),('vanilla-control-started',None),('vanilla-control-started',False),('vanilla-control-started','true')]:
with self.subTest(result=result,flag=flag):
done,report,_,_=self.archive('vanilla-control',result,flag)
self.assertEqual(done.returncode,1);self.assertTrue(report['ready'])
def test_control_retains_native_failure_despite_saved_success(self):
done,report,_,_=self.archive('vanilla-control','vanilla-control-started',True,content=BASE+"00 GUI (E): Unknown class 'SCR_WidgetExportRuleRoot'")
self.assertEqual(done.returncode,1);self.assertFalse(report['ready']);self.assertTrue(report['engine_errors'])
def test_cleanup_is_still_required(self):
done,_,_,_=self.archive('vanilla-control','vanilla-control-started',True,cleanup=False)
self.assertEqual(done.returncode,1)
def test_ordinary_current_and_legacy_status_remain_strict(self):
for flag in (None,False):
done,report,_,_=self.archive('core','game-started',flag)
self.assertEqual(done.returncode,0,done.stderr);self.assertTrue(report['normal_mission_ready'])
for result,flag in [('vanilla-control-started',False),('game-started',True)]:
done,_,_,_=self.archive('core',result,flag);self.assertEqual(done.returncode,1)
if __name__=='__main__':unittest.main()