summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2019-10-18 13:49:08 (GMT)
committerGitHub <noreply@github.com>2019-10-18 13:49:08 (GMT)
commitecb035cd14c11521276343397151929a94018a22 (patch)
tree34bb11f5c1a5f79996b66bba66472c73188a6959
parent5a88d50ff013a64fbdb25b877c87644a9034c969 (diff)
downloadcpython-ecb035cd14c11521276343397151929a94018a22.zip
cpython-ecb035cd14c11521276343397151929a94018a22.tar.gz
cpython-ecb035cd14c11521276343397151929a94018a22.tar.bz2
bpo-38502: regrtest uses process groups if available (GH-16829)
test.regrtest now uses process groups in the multiprocessing mode (-jN command line option) if process groups are available: if os.setsid() and os.killpg() functions are available.
-rw-r--r--Lib/test/libregrtest/runtest_mp.py29
-rw-r--r--Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst3
2 files changed, 25 insertions, 7 deletions
diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py
index 8026de1..fc12ea7 100644
--- a/Lib/test/libregrtest/runtest_mp.py
+++ b/Lib/test/libregrtest/runtest_mp.py
@@ -3,6 +3,7 @@ import faulthandler
import json
import os
import queue
+import signal
import subprocess
import sys
import threading
@@ -31,6 +32,8 @@ assert MAIN_PROCESS_TIMEOUT >= PROGRESS_UPDATE
# Time to wait until a worker completes: should be immediate
JOIN_TIMEOUT = 30.0 # seconds
+USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
+
def must_stop(result, ns):
if result.result == INTERRUPTED:
@@ -59,12 +62,16 @@ def run_test_in_subprocess(testname, ns):
# Running the child from the same working directory as regrtest's original
# invocation ensures that TEMPDIR for the child is the same when
# sysconfig.is_python_build() is true. See issue 15300.
+ kw = {}
+ if USE_PROCESS_GROUP:
+ kw['start_new_session'] = True
return subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
close_fds=(os.name != 'nt'),
- cwd=support.SAVEDCWD)
+ cwd=support.SAVEDCWD,
+ **kw)
def run_tests_worker(ns, test_name):
@@ -149,16 +156,24 @@ class TestWorkerProcess(threading.Thread):
return
self._killed = True
- print(f"Kill {self}", file=sys.stderr, flush=True)
+ if USE_PROCESS_GROUP:
+ what = f"{self} process group"
+ else:
+ what = f"{self}"
+
+ print(f"Kill {what}", file=sys.stderr, flush=True)
try:
- popen.kill()
+ if USE_PROCESS_GROUP:
+ os.killpg(popen.pid, signal.SIGKILL)
+ else:
+ popen.kill()
except ProcessLookupError:
- # Process completed, the TestWorkerProcess thread read its exit
- # status, but Popen.send_signal() read the returncode just before
- # Popen.wait() set returncode.
+ # popen.kill(): the process completed, the TestWorkerProcess thread
+ # read its exit status, but Popen.send_signal() read the returncode
+ # just before Popen.wait() set returncode.
pass
except OSError as exc:
- print_warning(f"Failed to kill {self}: {exc!r}")
+ print_warning(f"Failed to kill {what}: {exc!r}")
def stop(self):
# Method called from a different thread to stop this thread
diff --git a/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst b/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst
new file mode 100644
index 0000000..1df523e
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst
@@ -0,0 +1,3 @@
+test.regrtest now uses process groups in the multiprocessing mode (-jN command
+line option) if process groups are available: if :func:`os.setsid` and
+:func:`os.killpg` functions are available.