summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2021-05-11 17:39:38 +0100
committerMatthew Pickering <matthewtpickering@gmail.com>2021-05-12 08:25:50 +0100
commitdf8ef1a4865ed9d1ec0ac6f1f34465c118060933 (patch)
tree00e135f76db96c9e14a2997f0e0d9fa9cd42ecfd
parentad659f711a8e01c6035b9fc3a4074b031211d515 (diff)
downloadhaskell-wip/hpt-oneshot.tar.gz
testsuite: Teminate processes when the testsuite is interruptedwip/hpt-oneshot
-rw-r--r--testsuite/driver/runtests.py5
-rw-r--r--testsuite/driver/testlib.py20
-rw-r--r--testsuite/timeout/timeout.py53
3 files changed, 53 insertions, 25 deletions
diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py
index 39256aee5f..6335939245 100644
--- a/testsuite/driver/runtests.py
+++ b/testsuite/driver/runtests.py
@@ -465,6 +465,11 @@ else:
break
oneTest(watcher)
except KeyboardInterrupt:
+ # Signal we are stopping
+ stopNow()
+ # Acquire all slots in the semaphore
+ acquire_all()
+ # Exit
pass
# flush everything before we continue
diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py
index db40d6f82f..50f5133386 100644
--- a/testsuite/driver/testlib.py
+++ b/testsuite/driver/testlib.py
@@ -37,6 +37,11 @@ if config.use_threads:
import threading
pool_sema = threading.BoundedSemaphore(value=config.threads)
+def acquire_all() -> None:
+ global pool_sema
+ for i in range(config.threads):
+ pool_sema.acquire()
+
global wantToStop
wantToStop = False
@@ -2340,6 +2345,19 @@ def dump_file(f: Path):
except Exception:
print('')
+# Wait for a process but kill it if a global trigger is sent
+def process_loop(r):
+ finished = False
+ while not (stopping() or finished):
+ try:
+ r.wait(timeout=1)
+ finished = True
+ except subprocess.TimeoutExpired:
+ pass
+ if not finished:
+ r.terminate()
+ return r.communicate()
+
def runCmd(cmd: str,
stdin: Union[None, Path]=None,
stdout: Union[None, Path]=None,
@@ -2372,8 +2390,8 @@ def runCmd(cmd: str,
stdout=subprocess.PIPE,
stderr=hStdErr,
env=ghc_env)
+ stdout_buffer, stderr_buffer = process_loop(r)
- stdout_buffer, stderr_buffer = r.communicate()
finally:
if stdin_file:
stdin_file.close()
diff --git a/testsuite/timeout/timeout.py b/testsuite/timeout/timeout.py
index f3468ad9fb..d6bc0cf326 100644
--- a/testsuite/timeout/timeout.py
+++ b/testsuite/timeout/timeout.py
@@ -1,33 +1,33 @@
#!/usr/bin/env python
-try:
+import errno
+import os
+import signal
+import sys
+import time
- import errno
- import os
- import signal
- import sys
- import time
+secs = int(sys.argv[1])
+cmd = sys.argv[2]
- secs = int(sys.argv[1])
- cmd = sys.argv[2]
+def killProcess(pid):
+ os.killpg(pid, signal.SIGKILL)
+ for x in range(10):
+ try:
+ time.sleep(0.3)
+ r = os.waitpid(pid, os.WNOHANG)
+ if r == (0, 0):
+ os.killpg(pid, signal.SIGKILL)
+ else:
+ return
+ except OSError as e:
+ if e.errno == errno.ECHILD:
+ return
+ else:
+ raise e
- def killProcess(pid):
- os.killpg(pid, signal.SIGKILL)
- for x in range(10):
- try:
- time.sleep(0.3)
- r = os.waitpid(pid, os.WNOHANG)
- if r == (0, 0):
- os.killpg(pid, signal.SIGKILL)
- else:
- return
- except OSError as e:
- if e.errno == errno.ECHILD:
- return
- else:
- raise e
+pid = os.fork()
- pid = os.fork()
+try:
if pid == 0:
# child
os.setpgrp()
@@ -50,7 +50,12 @@ try:
sys.exit(99) # unexpected
except KeyboardInterrupt:
+ killProcess(pid)
sys.exit(98)
+except SystemExit:
+ raise
except:
+ print("Unexpected error:", sys.exc_info()[0])
+ killProcess(pid)
raise