Commit 0b81f67b authored by machenbach's avatar machenbach Committed by Commit bot

[test-runner] Improve test execution without tmp files for output.

BUG=chromium:485932
LOG=n

Review URL: https://codereview.chromium.org/1134703002

Cr-Commit-Position: refs/heads/master@{#28334}
parent 0208b8e3
...@@ -27,27 +27,13 @@ ...@@ -27,27 +27,13 @@
import os import os
import signal
import subprocess import subprocess
import sys from threading import Timer
import tempfile
import time
from ..local import utils from ..local import utils
from ..objects import output from ..objects import output
def KillProcessWithID(pid):
if utils.IsWindows():
os.popen('taskkill /T /F /PID %d' % pid)
else:
os.kill(pid, signal.SIGTERM)
MAX_SLEEP_TIME = 0.1
INITIAL_SLEEP_TIME = 0.0001
SLEEP_TIME_FACTOR = 1.25
SEM_INVALID_VALUE = -1 SEM_INVALID_VALUE = -1
SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h
...@@ -76,76 +62,36 @@ def RunProcess(verbose, timeout, args, **rest): ...@@ -76,76 +62,36 @@ def RunProcess(verbose, timeout, args, **rest):
prev_error_mode = Win32SetErrorMode(error_mode) prev_error_mode = Win32SetErrorMode(error_mode)
Win32SetErrorMode(error_mode | prev_error_mode) Win32SetErrorMode(error_mode | prev_error_mode)
process = subprocess.Popen( process = subprocess.Popen(
shell=utils.IsWindows(),
args=popen_args, args=popen_args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
**rest **rest
) )
if (utils.IsWindows() and prev_error_mode != SEM_INVALID_VALUE): if (utils.IsWindows() and prev_error_mode != SEM_INVALID_VALUE):
Win32SetErrorMode(prev_error_mode) Win32SetErrorMode(prev_error_mode)
# Compute the end time - if the process crosses this limit we
# consider it timed out.
if timeout is None: end_time = None
else: end_time = time.time() + timeout
timed_out = False
# Repeatedly check the exit code from the process in a
# loop and keep track of whether or not it times out.
exit_code = None
sleep_time = INITIAL_SLEEP_TIME
while exit_code is None:
if (not end_time is None) and (time.time() >= end_time):
# Kill the process and wait for it to exit.
KillProcessWithID(process.pid)
exit_code = process.wait()
timed_out = True
else:
exit_code = process.poll()
time.sleep(sleep_time)
sleep_time = sleep_time * SLEEP_TIME_FACTOR
if sleep_time > MAX_SLEEP_TIME:
sleep_time = MAX_SLEEP_TIME
return (exit_code, timed_out)
def PrintError(string): def kill_process(process, timeout_result):
sys.stderr.write(string) timeout_result[0] = True
sys.stderr.write("\n") try:
process.kill()
except OSError:
sys.stderr.write('Error: Process %s already ended.\n' % process.pid)
# Pseudo object to communicate with timer thread.
timeout_result = [False]
def CheckedUnlink(name): timer = Timer(timeout, kill_process, [process, timeout_result])
# On Windows, when run with -jN in parallel processes, timer.start()
# OS often fails to unlink the temp file. Not sure why. stdout, stderr = process.communicate()
# Need to retry. timer.cancel()
# Idea from https://bugs.webkit.org/attachment.cgi?id=75982&action=prettypatch return process.returncode, timeout_result[0], stdout, stderr
retry_count = 0
while retry_count < 30:
try:
os.unlink(name)
return
except OSError, e:
retry_count += 1
time.sleep(retry_count * 0.1)
PrintError("os.unlink() " + str(e))
def Execute(args, verbose=False, timeout=None): def Execute(args, verbose=False, timeout=None):
try: args = [ c for c in args if c != "" ]
args = [ c for c in args if c != "" ] exit_code, timed_out, stdout, stderr = RunProcess(
(fd_out, outname) = tempfile.mkstemp() verbose,
(fd_err, errname) = tempfile.mkstemp() timeout,
(exit_code, timed_out) = RunProcess( args=args,
verbose, )
timeout, return output.Output(exit_code, timed_out, stdout, stderr)
args=args,
stdout=fd_out,
stderr=fd_err
)
finally:
# TODO(machenbach): A keyboard interrupt before the assignment to
# fd_out|err can lead to reference errors here.
os.close(fd_out)
os.close(fd_err)
out = file(outname).read()
errors = file(errname).read()
CheckedUnlink(outname)
CheckedUnlink(errname)
return output.Output(exit_code, timed_out, out, errors)
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