32 lines
1.7 KiB
Python
32 lines
1.7 KiB
Python
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import time
|
|
from pathlib import Path
|
|
from unittest import TestCase
|
|
from arm_application.process_lifecycle import stop_process_tree,_stat
|
|
|
|
|
|
class ProcessTreeTest(TestCase):
|
|
def test_descendants_in_other_sessions_exit_without_touching_unrelated_process(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
script=Path(directory)/'child.py'
|
|
script.write_text("import subprocess,sys,time,os\nfrom pathlib import Path\np=subprocess.Popen([sys.executable,'-c','import time;time.sleep(120)'],start_new_session=True)\nPath(sys.argv[1]).write_text(str(p.pid))\ntime.sleep(120)\n")
|
|
pidfile=Path(directory)/'pid'
|
|
unrelated=subprocess.Popen([sys.executable,'-c','import time;time.sleep(120)'],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
|
|
root=subprocess.Popen([sys.executable,str(script),str(pidfile)],start_new_session=True,stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
|
|
try:
|
|
deadline=time.monotonic()+3
|
|
while not pidfile.exists() and time.monotonic()<deadline:time.sleep(.02)
|
|
self.assertTrue(pidfile.exists());child=int(pidfile.read_text())
|
|
self.assertNotEqual(os.getpgid(child),os.getpgid(root.pid))
|
|
stop_process_tree(root,interrupt_timeout=1,terminate_timeout=1)
|
|
self.assertIsNotNone(root.poll())
|
|
state=_stat(child)
|
|
self.assertTrue(state is None or state[2]=='Z')
|
|
self.assertIsNone(unrelated.poll())
|
|
finally:
|
|
if root.poll() is None:stop_process_tree(root,interrupt_timeout=.2,terminate_timeout=.2)
|
|
unrelated.terminate();unrelated.wait(timeout=2)
|