Files
EscapistsReintroduced/tests/test_aircraft_field_runner.py
jakub cab998fb64 Combine Workshop addon and fix prison startup
Merge owned systems into one addon while preserving resource identities. Gate player admission on the replicated prison scene, restore the original framed door, and hold enemy AI until escape. Correct scenario branding and author metadata, include publishing assets, and retain regression and native verification evidence.
2026-09-20 16:42:52 +02:00

59 lines
4.2 KiB
Python

"""Actual early CLI refusals and AST-executed argv construction; never launches native tools."""
import ast
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
from types import SimpleNamespace
from policy_harness import ROOT
RUNNER=ROOT/'tools/headless_workbench.py'
class FieldRunnerTests(unittest.TestCase):
def test_early_refusal_before_any_profile_or_lock(self):
cases=[
(['--project','chat','--rounds','1','--timeout','420','--smoke','aircraft-route','--field-terrain-audit'],'--field-terrain-audit requires'),
(['--project','chat','--rounds','1','--timeout','420','--smoke','aircraft-field','--field-terrain-audit','--field-service-cancel'],'mutually exclusive'),
(['--project','chat','--rounds','1','--timeout','420','--smoke','aircraft-field','--field-terrain-audit'],'must be a disposable cloned prefix'),
(['--project','core','--rounds','1','--timeout','420','--smoke','aircraft-field'],'requires Chat, one round'),
(['--project','chat','--rounds','2','--timeout','420','--smoke','aircraft-field'],'requires Chat, one round'),
(['--project','chat','--rounds','1','--timeout','419','--smoke','aircraft-field'],'requires Chat, one round'),
(['--project','chat','--rounds','1','--timeout','420','--smoke','aircraft-route','--field-service-cancel'],'--field-service-cancel requires'),
(['--project','chat','--rounds','1','--timeout','420','--smoke','aircraft-field','--route-service-cancel'],'--route-service-cancel requires'),
(['--project','chat','--rounds','1','--timeout','420','--smoke','aircraft-field'],'must be a disposable cloned prefix'),
(['--project','chat','--rounds','1','--timeout','420','--smoke','aircraft-field','--field-service-cancel'],'must be a disposable cloned prefix'),
]
for arguments,error in cases:
with self.subTest(arguments=arguments),tempfile.TemporaryDirectory(prefix='erri-field-args-') as folder:
root=Path(folder)
result=subprocess.run([sys.executable,str(RUNNER),'--compat',str(root/'missing'),'--profile',str(root/'profile'),*arguments],capture_output=True,text=True,timeout=10)
self.assertEqual(result.returncode,2);self.assertIn(error,result.stderr);self.assertEqual(list(root.iterdir()),[])
def command(self,smoke,cancel=False,audit=False):
tree=ast.parse(RUNNER.read_text());nodes=[]
for node in tree.body:
if isinstance(node,ast.Assign) and any(isinstance(t,ast.Name) and t.id=='command' for t in node.targets):nodes.append(node)
if isinstance(node,ast.If) and isinstance(node.test,ast.Attribute) and node.test.attr in ('field_service_cancel','route_service_cancel','field_terrain_audit'):nodes.append(node)
self.assertEqual(len(nodes),4)
namespace={'a':SimpleNamespace(project='chat',smoke=smoke,field_service_cancel=cancel,route_service_cancel=False,field_terrain_audit=audit),'ROOT':Path('/private/source'),'proton':Path('/private/proton'),'wb':Path('/private/workbench'),'profile_arg':'Z:/private/profile'}
exec(compile(ast.Module(body=nodes,type_ignores=[]),str(RUNNER),'exec'),namespace)
return namespace['command']
def test_exact_field_command_and_cancel_optin(self):
normal=self.command('aircraft-field');cancelled=self.command('aircraft-field',True)
self.assertEqual(cancelled,normal+['-errSmokeFieldServiceCancel','1'])
self.assertEqual(normal[normal.index('-errSmokeOutcome')+1],'aircraft-field')
self.assertEqual(normal[normal.index('-gproj')+1],'Z:/private/source/addons/core/addon.gproj')
self.assertEqual(normal[normal.index('--backend')+1],'headless')
self.assertIn('-disableCrashReporter',normal)
self.assertNotIn('-errSmokeFieldServiceCancel',self.command('aircraft-route'))
def test_terrain_audit_adds_only_explicit_flag(self):
normal=self.command('aircraft-field')
self.assertEqual(self.command('aircraft-field',audit=True),normal+['-errSmokeFieldTerrainAudit','1'])
self.assertNotIn('-errSmokeFieldTerrainAudit',normal)
self.assertNotIn('-errSmokeFieldTerrainAudit',self.command('aircraft-route'))
def test_cleanup_provenance_not_bypassed(self):
source=RUNNER.read_text()
self.assertIn('assert_prefix_idle(compat)',source)
self.assertIn('cleanup_owned_run(',source)
self.assertIn('seal_run(',source)
self.assertIn("env.update(PULSE_SINK=silent_sink",source)
if __name__=='__main__':unittest.main()