Advance standalone admission, finite artillery and native validation

This commit is contained in:
2026-09-19 09:02:31 +02:00
parent af5146a317
commit 40a474934c
532 changed files with 56456 additions and 199 deletions
+104
View File
@@ -0,0 +1,104 @@
"""Synthetic files test no-launch planning; never execute a server or client."""
import json
from pathlib import Path
import sys
import tempfile
import unittest
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]/'tools'))
import dedicated_preflight as tool
class DedicatedPreflightTests(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
self.addCleanup(self.tmp.cleanup)
root = Path(self.tmp.name)
self.source, self.runtime = root/'source', root/'runtime'
self.runtime.mkdir()
for project, header in tool.HEADERS.items():
addon = self.source/'addons'/project
path = addon/header
path.parent.mkdir(parents=True)
(addon/'addon.gproj').write_text('GameProject { GUID "2528466DE220D91C" }')
path.write_text('SCR_MissionHeader { World "'+tool.WORLD+'" SystemsConfig "'+tool.SYSTEMS+'" }')
path.with_suffix('.conf.meta').write_text('MetaFileClass { Name "{AD62322D5213C440}'+header+'" }')
(self.runtime/'runtime-origin.json').write_text(json.dumps({'app_id':1874900,'purpose':'private anonymous Reforger dedicated server preparation; no server launched'}))
def plan(self, **kwargs):
return tool.build_plan(self.source,self.runtime,**kwargs)
def installed(self, app='1874900', architecture=62):
directory=self.runtime/'server';directory.mkdir(exist_ok=True)
binary=directory/'ArmaReforgerServer'
data=bytearray(20);data[:6]=b'\x7fELF\x02\x01';data[18:20]=architecture.to_bytes(2,'little')
binary.write_bytes(data);binary.chmod(0o700)
manifests=directory/'steamapps';manifests.mkdir(exist_ok=True)
(manifests/'appmanifest_1874900.acf').write_text('"AppState" { "appid" "'+app+'" "buildid" "synthetic-build" "StateFlags" "4" }')
return binary
def test_missing_runtime_still_prepares_strict_loopback_review(self):
result,config,_=self.plan()
self.assertFalse(result['launch_allowed']);self.assertFalse(result['multiplayer_passed'])
self.assertEqual(result['genuine_clients_verified'],0)
self.assertIn('missing or incomplete',result['blockers'][0])
self.assertEqual(config['bindAddress'],'127.0.0.1')
self.assertEqual(config['publicAddress'],'127.0.0.1')
self.assertFalse(config['game']['visible'])
self.assertTrue(config['game']['gameProperties']['fastValidation'])
self.assertTrue(config['game']['gameProperties']['battlEye'])
self.assertTrue(config['operating']['disableCrashReporter'])
self.assertNotIn('rcon',config);self.assertNotIn('a2s',config)
def test_binary_is_inspected_never_executed_and_cannot_establish_mp(self):
self.installed()
with patch('subprocess.run',side_effect=AssertionError('must not run')),patch('subprocess.Popen',side_effect=AssertionError('must not spawn')):
result,_,_=self.plan()
runtime=result['runtime']
self.assertTrue(runtime['binary_elf_x86_64']);self.assertTrue(runtime['install_complete'])
self.assertEqual(runtime['steam_build_id'],'synthetic-build')
self.assertIsNone(runtime['engine_version']);self.assertFalse(runtime['native_runtime_executed'])
self.assertFalse(result['launch_allowed']);self.assertTrue(result['blockers'])
def test_wrong_app_rejected_wrong_arch_incomplete(self):
self.installed(app='1890870')
with self.assertRaisesRegex(ValueError,'stable dedicated'):self.plan()
self.installed(architecture=183)
result,_,_=self.plan();self.assertFalse(result['runtime']['binary_elf_x86_64'])
self.assertIn('missing or incomplete',result['blockers'][0])
def test_symlink_to_existing_server_rejected(self):
binary=self.installed();target=self.runtime/'other-server';binary.rename(target);binary.symlink_to(target)
with self.assertRaisesRegex(ValueError,'symlink'):self.plan()
def test_header_and_port_validation(self):
for port in (0,1023,65536):
with self.assertRaisesRegex(ValueError,'unprivileged'):self.plan(port=port)
header=self.source/'addons/core'/tool.HEADERS['core']
header.write_text(header.read_text().replace(tool.SYSTEMS,'wrong'))
with self.assertRaisesRegex(ValueError,'SystemsConfig'):self.plan()
def test_project_selection_and_source_snapshot_change(self):
before,config,_=self.plan(project='chat')
self.assertEqual(before['scenario']['project'],'chat')
self.assertTrue(config['game']['scenarioId'].endswith(tool.HEADERS['chat']))
(self.source/'addons/core/new.c').write_text('// independent new source')
after,_,_=self.plan(project='chat')
self.assertNotEqual(before['source_manifest_sha256'],after['source_manifest_sha256'])
def test_write_new_private_review_only_preserves_existing_evidence(self):
result,config,manifest=self.plan();destination=self.runtime/'review'
tool.write_plan(destination,result,config,manifest)
self.assertEqual(json.loads((destination/'server-config.review.json').read_text()),config)
self.assertFalse(json.loads((destination/'preflight.json').read_text())['listener_started'])
self.assertEqual(tool.digest(destination/'source-manifest.json'),result['source_manifest_sha256'])
with self.assertRaisesRegex(ValueError,'never overwritten'):tool.write_plan(destination,result,config,manifest)
with self.assertRaisesRegex(ValueError,'direct child'):tool.write_plan(self.source/'review',result,config,manifest)
def test_unmarked_runtime_and_source_overlap_refused(self):
result,config,manifest=self.plan();(self.runtime/'runtime-origin.json').unlink()
with self.assertRaisesRegex(ValueError,'origin marker'):tool.write_plan(self.runtime/'review',result,config,manifest)
with self.assertRaisesRegex(ValueError,'separate'):tool.build_plan(self.source,self.source/'runtime')
if __name__=='__main__':unittest.main()