Commit bb278115 authored by Michael Achenbach's avatar Michael Achenbach Committed by Commit Bot

[test] Ensure restoring of signal handler when tests terminate

Otherwise, the last tests that ran in a worker keep sitting on their
sigterm handlers without any running processes. This creates
exceptions when workers terminate.

Bug: v8:8292
Change-Id: Iefb9a4a353399c1e3168eae2916e3cedca4e09b3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2011831Reviewed-by: 's avatarTamer Tas <tmrts@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65907}
parent 9e3f6070
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
# for py2/py3 compatibility # for py2/py3 compatibility
from __future__ import print_function from __future__ import print_function
from contextlib import contextmanager
import os import os
import re import re
import signal import signal
...@@ -39,6 +40,28 @@ class AbortException(Exception): ...@@ -39,6 +40,28 @@ class AbortException(Exception):
pass pass
@contextmanager
def handle_sigterm(process, handle_sigterm):
"""Handle sigterm for `process` and restore previous handler to prevent
erroneous termination of an already terminated process.
"""
# Variable to communicate with the signal handler.
abort_occured = [False]
def handler(signum, frame):
self._abort(process, abort_occured)
if handle_sigterm:
previous = signal.signal(signal.SIGTERM, handler)
try:
yield
finally:
if handle_sigterm:
signal.signal(signal.SIGTERM, previous)
if abort_occured[0]:
raise AbortException()
class BaseCommand(object): class BaseCommand(object):
def __init__(self, shell, args=None, cmd_prefix=None, timeout=60, env=None, def __init__(self, shell, args=None, cmd_prefix=None, timeout=60, env=None,
verbose=False, resources_func=None, handle_sigterm=False): verbose=False, resources_func=None, handle_sigterm=False):
...@@ -72,28 +95,18 @@ class BaseCommand(object): ...@@ -72,28 +95,18 @@ class BaseCommand(object):
process = self._start_process() process = self._start_process()
# Variable to communicate with the signal handler. with handle_sigterm(process, self.handle_sigterm):
abort_occured = [False] # Variable to communicate with the timer.
def handler(signum, frame): timeout_occured = [False]
self._abort(process, abort_occured) timer = threading.Timer(
self.timeout, self._abort, [process, timeout_occured])
if self.handle_sigterm: timer.start()
signal.signal(signal.SIGTERM, handler)
# Variable to communicate with the timer.
timeout_occured = [False]
timer = threading.Timer(
self.timeout, self._abort, [process, timeout_occured])
timer.start()
start_time = time.time()
stdout, stderr = process.communicate()
duration = time.time() - start_time
timer.cancel() start_time = time.time()
stdout, stderr = process.communicate()
duration = time.time() - start_time
if abort_occured[0]: timer.cancel()
raise AbortException()
return output.Output( return output.Output(
process.returncode, process.returncode,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment