mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
Attempt independent resource cleanup without losing primary failures, retain unresolved owners, and publish completion after release. Bound existing producer commands, preserve helper return values, and settle startup and fixture children on failure. Validation: 29 focused boundary tests passed; actual helper-value and import-bound filesystem cleanup controls passed. The real inert-child termination control and targeted JavaScript binding checks passed, alongside typecheck, lint and formatting. Live Ghidra, Cutter, Electron GUI and Windows addon qualification was not run.
61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
#!/usr/bin/env python3
|
|
import importlib.util
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
helper_path = sys.argv[1]
|
|
spec = importlib.util.spec_from_file_location("hopper_demo_x11", helper_path)
|
|
if spec is None or spec.loader is None:
|
|
raise SystemExit("unable to load helper")
|
|
helper = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(helper)
|
|
|
|
child = subprocess.Popen(
|
|
[
|
|
sys.executable,
|
|
"-c",
|
|
(
|
|
"import signal,time;"
|
|
"signal.signal(signal.SIGTERM, signal.SIG_IGN);"
|
|
"print('ready', flush=True);"
|
|
"time.sleep(100)"
|
|
),
|
|
],
|
|
stdout=subprocess.PIPE,
|
|
text=True,
|
|
)
|
|
try:
|
|
assert child.stdout is not None
|
|
if child.stdout.readline().strip() != "ready":
|
|
raise SystemExit("child did not become ready")
|
|
|
|
started = time.monotonic()
|
|
helper.stop_process(child)
|
|
elapsed = time.monotonic() - started
|
|
|
|
print(
|
|
json.dumps(
|
|
{
|
|
"returncode": child.returncode,
|
|
"elapsed_ms": round(elapsed * 1000),
|
|
},
|
|
separators=(",", ":"),
|
|
)
|
|
)
|
|
|
|
if child.returncode != -9:
|
|
raise SystemExit(f"expected SIGKILL fallback, got {child.returncode}")
|
|
if not 1800 <= elapsed * 1000 < 4000:
|
|
raise SystemExit(f"unexpected cleanup duration: {elapsed}")
|
|
finally:
|
|
# This exact Popen is fixture-owned even when stop_process under test fails.
|
|
try:
|
|
if child.poll() is None:
|
|
child.kill()
|
|
child.wait(timeout=2)
|
|
finally:
|
|
if child.stdout is not None:
|
|
child.stdout.close()
|