Deal with timeouts when running test cases.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@32 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 69b74a95
...@@ -33,6 +33,7 @@ import os ...@@ -33,6 +33,7 @@ import os
from os.path import join, dirname, abspath, basename from os.path import join, dirname, abspath, basename
import platform import platform
import re import re
import signal
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
...@@ -260,7 +261,7 @@ class TestCase(object): ...@@ -260,7 +261,7 @@ class TestCase(object):
def Run(self): def Run(self):
command = self.GetCommand() command = self.GetCommand()
output = Execute(command, self.context) output = Execute(command, self.context, self.context.timeout)
return TestOutput(self, command, output) return TestOutput(self, command, output)
...@@ -286,33 +287,54 @@ class TestOutput(object): ...@@ -286,33 +287,54 @@ class TestOutput(object):
return execution_failed return execution_failed
def KillProcessWithID(pid):
if platform.system() == 'Windows':
os.popen('taskkill /T /F /PID %d' % pid)
else:
os.kill(pid, signal.SIGTERM)
MAX_SLEEP_TIME = 0.1 MAX_SLEEP_TIME = 0.1
INITIAL_SLEEP_TIME = 0.0001 INITIAL_SLEEP_TIME = 0.0001
SLEEP_TIME_FACTOR = 1.25 SLEEP_TIME_FACTOR = 1.25
def RunProcess(context, **args): def RunProcess(context, timeout, **args):
if context.verbose: print "#", " ".join(args['args']) if context.verbose: print "#", " ".join(args['args'])
process = subprocess.Popen( process = subprocess.Popen(
shell = (platform.system() == 'Windows'), shell = (platform.system() == 'Windows'),
**args **args
) )
# 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 exit_code = None
sleep_time = INITIAL_SLEEP_TIME sleep_time = INITIAL_SLEEP_TIME
while exit_code is None: while exit_code is None:
exit_code = process.poll() if (not end_time is None) and (time.time() >= end_time):
time.sleep(sleep_time) # Kill the process and wait for it to exit.
sleep_time = sleep_time * SLEEP_TIME_FACTOR KillProcessWithID(process.pid)
if sleep_time > MAX_SLEEP_TIME: exit_code = process.wait()
sleep_time = MAX_SLEEP_TIME timed_out = True
return (process, exit_code) 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 (process, exit_code, timed_out)
def Execute(args, context): def Execute(args, context, timeout=None):
(fd_out, outname) = tempfile.mkstemp() (fd_out, outname) = tempfile.mkstemp()
(fd_err, errname) = tempfile.mkstemp() (fd_err, errname) = tempfile.mkstemp()
(process, exit_code) = RunProcess( (process, exit_code, timed_out) = RunProcess(
context, context,
timeout,
args = args, args = args,
stdout = fd_out, stdout = fd_out,
stderr = fd_err, stderr = fd_err,
...@@ -326,9 +348,10 @@ def Execute(args, context): ...@@ -326,9 +348,10 @@ def Execute(args, context):
return CommandOutput(exit_code, output, errors) return CommandOutput(exit_code, output, errors)
def ExecuteNoCapture(args, context): def ExecuteNoCapture(args, context, timeout=None):
(process, exit_code) = RunProcess( (process, exit_code, timed_out) = RunProcess(
context, context,
timeout,
args = args, args = args,
) )
return CommandOutput(exit_code, "", "") return CommandOutput(exit_code, "", "")
......
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