Files
TheTree_mock/tools/regression/owned_outer.py
T
Takeshi b84bade045 Save The Tree implementation and acceptance work in progress
Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
2026-10-11 15:58:00 +09:00

77 lines
4.1 KiB
Python

"""Future owned admission: immutable e31/c007 plus actual-Popen outer capture.
Path r02 finish_captured is copied literally below. Fake controls are not actual
engine evidence. No PID discovery or foreign/group signals are used for cleanup.
"""
from pathlib import Path
import importlib.util, subprocess
HERE=Path(__file__).resolve().parent
spec=importlib.util.spec_from_file_location('exact_e31_full_native',HERE/'owned_diagnostic_process.py')
native=importlib.util.module_from_spec(spec);spec.loader.exec_module(native)
OWNED=[]
def finish_captured(processes, cleanup_fn=None):
"""Bound caller interruptions per captured object; never discover or signal others.
The immutable helper itself has at most3 waits of5s. At most3 calls here
handle an exception escaping that helper boundary, not a general I/O bound.
Every error stays fatal to the phase even if a later cleanup confirms ended.
"""
cleanup_fn = cleanup_fn or native.cleanup_actual_owned_child
rows = []; errors = []
for process in processes:
cleanup = None; caught_errors = []
for attempt in range(3):
try:
cleanup = cleanup_fn(process); break
except BaseException as caught:
caught_errors.append(type(caught).__name__ + ': ' + str(caught))
ended = isinstance(cleanup, dict) and cleanup.get('engine_ended') is True
helper_errors = cleanup.get('errors', []) if isinstance(cleanup, dict) else []
rows.append({'pid': process.pid, 'cleanup': cleanup,
'outer_cleanup_errors': caught_errors, 'engine_ended': ended if cleanup is not None else None,
'outer_maximum_helper_invocations': 3, 'helper_maximum_waits': 3,
'per_wait_timeout_seconds': 5, 'foreign_process_or_group_signals': 0})
if caught_errors or not ended or helper_errors:
errors.append('captured child cleanup incomplete/interrupted ' + str(process.pid))
return rows, errors
def run_phase(argv, folder, timeout, env, *, now_fn, dump_fn, sha_fn, live_engines_fn,
popen_fn=None, diagnostic_fn=None, cleanup_fn=None):
"""Capture actual object before adapter receipt work; always clean before I/O.
A START/END/outer write failure stays fatal even after child termination.
The full runner also retains OWNED for one final bounded sweep before guards.
"""
actual_popen=popen_fn or subprocess.Popen
diagnostic_fn=diagnostic_fn or native.run_owned_diagnostic
captured=[]
def spawn(command, **options):
process=actual_popen(command,**options)
captured.append(process);OWNED.append(process)
return process
result=None;error=None;rows=[];errors=[]
try:
result=diagnostic_fn(argv,folder,timeout,env,now_fn=now_fn,dump_fn=dump_fn,
sha_fn=sha_fn,live_engines_fn=live_engines_fn,popen_fn=spawn)
except BaseException as caught:
error=type(caught).__name__+': '+str(caught)
finally:
rows,errors=finish_captured(captured,cleanup_fn)
outer={'actual_captured_pids':[p.pid for p in captured],'cleanup':rows,
'adapter_exception':error,'all_captured_ended':bool(captured) and all(r['engine_ended'] is True for r in rows),
'outer_cleanup_errors':errors,'foreign_process_or_group_signals':0,
'all_cleanup_before_outer_receipt':True,'outer_receipt_written':False,'outer_receipt_error':None}
try:
# Existence plus SHA confirms durability; the file cannot truthfully
# describe whether its own future write has returned. Keep that result
# in the caller's later phase receipt, separate from actual child exit.
body={key:value for key,value in outer.items()
if key not in ['outer_receipt_written','outer_receipt_error']}
dump_fn(Path(folder)/'outer-owned-finally.json',body)
outer['outer_receipt_written']=True
except BaseException as caught:
outer['outer_receipt_error']=type(caught).__name__+': '+str(caught)
outer['passed']=bool(result) and error is None and outer['all_captured_ended'] and not errors and outer['outer_receipt_written']
return result,outer