the-custodian/docs/changes/netkingdom-target-2026-10-17/native-runtime-install-r3/test_process_supervision.py
codex 4016f3bdee
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Reject generated-only commits / generated-commit-guard (push) Successful in 9s
Record failed runtime trial and reviewed verification proposal (3/4)
2026-10-17 13:27:00 +02:00

130 lines
7.8 KiB
Python

#!/usr/bin/env python3
"""Disposable actual process-tree oracles; never invoke runtime, SSH or bwrap."""
import ctypes
import importlib.util
import json
import os
from pathlib import Path
import select
import signal
import subprocess
import sys
import tempfile
import time
import unittest
HERE=Path(__file__).resolve().parent
SPEC=importlib.util.spec_from_file_location('supervised',HERE/'process_supervision.py')
S=importlib.util.module_from_spec(SPEC);SPEC.loader.exec_module(S)
CANARY='fixture-private-stderr-must-not-appear'
# A session-escaping grandchild remains owned by the subreaper even after the
# intermediate process exits. No namespace or application launcher is involved.
LEAF="import os,time,sys;from pathlib import Path;Path(sys.argv[1]).write_text(str(os.getpid()));print(sys.argv[2],file=sys.stderr,flush=True);time.sleep(30)"
LEADER="import subprocess,sys,time;subprocess.Popen([sys.executable,'-c',sys.argv[1],sys.argv[2],sys.argv[3]],start_new_session=True);time.sleep(30)"
def wait_until(predicate,timeout=8):
end=time.monotonic()+timeout
while time.monotonic()<end:
if predicate():return
time.sleep(.02)
raise AssertionError('bounded fixture condition failed')
def not_alive(pid):
f=S.facts(pid)
return f is None or f['state']=='Z'
class ProcessSupervisionTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Reap only the known detached fixture watchdog after killed-controller
# tests, so this test does not depend on the workstation PID1 reaper.
assert ctypes.CDLL(None).prctl(36,1,0,0,0)==0
def setUp(self):
self.temp=tempfile.TemporaryDirectory(prefix='nk-supervision-fixture-')
self.base=Path(self.temp.name);self.sentinel=subprocess.Popen([sys.executable,'-c','import time;time.sleep(30)'])
self.addCleanup(self.cleanup)
def cleanup(self):
self.sentinel.terminate();self.sentinel.wait(timeout=3);self.temp.cleanup()
def argv(self,marker):return [sys.executable,'-c',LEADER,LEAF,str(marker),CANARY]
def assert_quiet(self,state,pid):
wait_until(lambda:(state/'quiescent.json').exists())
r=json.loads((state/'quiescent.json').read_text())
self.assertTrue(r['quiescent']);self.assertTrue(r['no_live_or_waitable_descendants'])
wait_until(lambda:not_alive(pid));self.assertIsNone(self.sentinel.poll())
for p in state.glob('*.json'):
if p.name.startswith('request-'):continue # test input deliberately contains canary
self.assertNotIn(CANARY,p.read_text())
return r
def test_success_and_bounded_stdout(self):
s=S.Supervisor(self.base/'state')
self.assertEqual(s.run([sys.executable,'-c','print("receipt")'],2,capture=True),(0,b'receipt\n'))
self.assertTrue(s.close()['quiescent'])
def test_timeout_reaps_session_escaped_descendant_and_retains_sibling(self):
state=self.base/'state';marker=self.base/'child';s=S.Supervisor(state)
code,output=s.run(self.argv(marker),.6,capture=True)
self.assertEqual(code,124);self.assertEqual(output,b'')
self.assertTrue(marker.exists());r=self.assert_quiet(state,int(marker.read_text()))
self.assertEqual(r['reason'],'timeout');self.assertTrue(s.close()['quiescent'])
def test_hard_controller_loss_reaps_descendant_and_retains_stage(self):
state=self.base/'state';marker=self.base/'child'
controller="import importlib.util,sys;from pathlib import Path;s=importlib.util.spec_from_file_location('s',sys.argv[1]);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);x=m.Supervisor(Path(sys.argv[2]));x.run(sys.argv[3:],20,capture=True)"
p=subprocess.Popen([sys.executable,'-I','-B','-c',controller,str(HERE/'process_supervision.py'),str(state),*self.argv(marker)],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
self.addCleanup(lambda:p.poll() is None and p.kill())
wait_until(marker.exists);watchdog=json.loads((state/'ready.json').read_text())['pid']
os.kill(p.pid,signal.SIGKILL);p.wait(timeout=3)
r=self.assert_quiet(state,int(marker.read_text()));self.assertEqual(r['reason'],'controller_lost')
self.assertTrue(state.exists()) # no controller remains to delete its stage
wait_until(lambda:not_alive(watchdog));os.waitpid(watchdog,0)
def test_outer_phase_timeout_stops_nested_runner_sibling(self):
state=self.base/'state';marker=self.base/'child';s=S.Supervisor(state)
phase="import importlib.util,sys;from pathlib import Path;s=importlib.util.spec_from_file_location('s',sys.argv[1]);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);m.request(Path(sys.argv[2]),sys.argv[3:],20)"
code,output=s.run([sys.executable,'-I','-B','-c',phase,str(HERE/'process_supervision.py'),str(state),*self.argv(marker)],.7,capture=True)
self.assertEqual(code,124);self.assertTrue(marker.exists())
self.assert_quiet(state,int(marker.read_text()));self.assertTrue(s.close()['quiescent'])
def test_dead_adopted_zombie_is_reaped_without_false_live_failure(self):
state=self.base/'state';s=S.Supervisor(state)
code="import os,time;pid=os.fork();os._exit(0) if pid==0 else None;time.sleep(.1)"
rc,out=s.run([sys.executable,'-B','-c',code],2,capture=True)
self.assertEqual(rc,0);report=s.close();self.assertTrue(report['quiescent'])
self.assertTrue(report['reaped_orphan_zombies'])
self.assertTrue(all(x['facts']['state']=='Z' and x['exit_code']==0 for x in report['reaped_orphan_zombies']))
def test_true_live_orphan_still_refuses_and_reports_exact_public_state(self):
state=self.base/'state';marker=self.base/'child';s=S.Supervisor(state)
code="import subprocess,sys,time;subprocess.Popen([sys.executable,'-c',sys.argv[1],sys.argv[2],sys.argv[3]],start_new_session=True);time.sleep(.1)"
rc,out=s.run([sys.executable,'-B','-c',code,LEAF,str(marker),CANARY],2,capture=False)
self.assertEqual(rc,125);report=self.assert_quiet(state,int(marker.read_text()))
self.assertEqual(report['reason'],'leader_left_descendants');self.assertTrue(report['leftover_at_failure'])
self.assertTrue(any(x['state']!='Z' for x in report['leftover_at_failure']))
self.assertTrue(s.close()['quiescent'])
def test_three_nested_launcher_receipts_survive_normal_zombie_reaping(self):
state=self.base/'state';s=S.Supervisor(state)
phase="import importlib.util,sys,json;s=importlib.util.spec_from_file_location('s',sys.argv[1]);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);code='import os,time;pid=os.fork();os._exit(0) if pid==0 else None;time.sleep(.08)';results={name:m.request(sys.argv[2],[sys.executable,'-B','-c',code],2,label=name)[0] for name in ('rein-aharness','glas-harness','claude')};print(json.dumps(results))"
rc,out=s.run([sys.executable,'-I','-B','-c',phase,str(HERE/'process_supervision.py'),str(state)],5,capture=True,label='rehearsal-phase')
self.assertEqual(rc,0);self.assertEqual(json.loads(out),{'rein-aharness':0,'glas-harness':0,'claude':0})
report=s.close();self.assertEqual(len(report['jobs']),4);self.assertEqual(len(report['reaped_orphan_zombies']),3)
self.assertTrue(all(x['status']=='completed' and x['returncode']==0 for x in report['jobs']))
def test_invalid_mapping_retains_failed_quiescence_evidence(self):
state=self.base/'state';s=S.Supervisor(state);owner=S.facts(os.getpid());owner['start']+=1
S.write(state/'request-invalid.json',{'owner':owner,'argv':[sys.executable,'-c','pass'],'timeout':1,'capture':False})
wait_until(lambda:(state/'quiescent.json').exists())
self.assertFalse(json.loads((state/'quiescent.json').read_text())['quiescent'])
with self.assertRaises(RuntimeError):s.close()
self.assertTrue(state.exists());self.assertIsNone(self.sentinel.poll())
if __name__=='__main__':unittest.main()