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 16:54:34 +0100
commit529236d0d39a5d6457fa517d4f6c118300fe5daa (patch)
treec60d90dd2162495fbd11c495be399584ef25beb6
parent736d47ffb7370ba4348b142c913b88e4c82347d0 (diff)
downloadhaskell-wip/testsuite-cleanup.tar.gz
testsuite: Teminate processes when the testsuite is interruptedwip/testsuite-cleanup
-rw-r--r--testsuite/driver/runtests.py5
-rw-r--r--testsuite/driver/testlib.py22
-rw-r--r--testsuite/timeout/timeout.py53
3 files changed, 55 insertions, 25 deletions
diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py
index 98d6c134b9..a64f9a1a25 100644
--- a/testsuite/driver/runtests.py
+++ b/testsuite/driver/runtests.py
@@ -462,6 +462,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 2bcbc543ce..50ed7e5551 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
@@ -2370,6 +2375,21 @@ 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:
+ # communicate rather than wait so that doesn't block on stdin
+ out,errs = r.communicate(timeout=1)
+ finished = True
+ except subprocess.TimeoutExpired:
+ pass
+ if not finished:
+ r.terminate()
+ out, errs = r.communicate()
+ return out,errs
+
def runCmd(cmd: str,
stdin: Union[None, Path]=None,
stdout: Union[None, Path]=None,
@@ -2402,8 +2422,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