diff options
Diffstat (limited to 'deps/v8/tools/testrunner/local/command.py')
-rw-r--r-- | deps/v8/tools/testrunner/local/command.py | 113 |
1 files changed, 103 insertions, 10 deletions
diff --git a/deps/v8/tools/testrunner/local/command.py b/deps/v8/tools/testrunner/local/command.py index adc9c2e4523..302d568e875 100644 --- a/deps/v8/tools/testrunner/local/command.py +++ b/deps/v8/tools/testrunner/local/command.py @@ -4,16 +4,22 @@ import os +import re import signal import subprocess import sys import threading import time +from ..local.android import ( + android_driver, CommandFailedException, TimeoutException) from ..local import utils from ..objects import output +BASE_DIR = os.path.normpath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), '..' , '..', '..')) + SEM_INVALID_VALUE = -1 SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h @@ -33,7 +39,18 @@ class AbortException(Exception): class BaseCommand(object): def __init__(self, shell, args=None, cmd_prefix=None, timeout=60, env=None, - verbose=False): + verbose=False, resources_func=None): + """Initialize the command. + + Args: + shell: The name of the executable (e.g. d8). + args: List of args to pass to the executable. + cmd_prefix: Prefix of command (e.g. a wrapper script). + timeout: Timeout in seconds. + env: Environment dict for execution. + verbose: Print additional output. + resources_func: Callable, returning all test files needed by this command. + """ assert(timeout > 0) self.shell = shell @@ -43,11 +60,11 @@ class BaseCommand(object): self.env = env or {} self.verbose = verbose - def execute(self, **additional_popen_kwargs): + def execute(self): if self.verbose: print '# %s' % self - process = self._start_process(**additional_popen_kwargs) + process = self._start_process() # Variable to communicate with the signal handler. abort_occured = [False] @@ -79,14 +96,13 @@ class BaseCommand(object): duration ) - def _start_process(self, **additional_popen_kwargs): + def _start_process(self): try: return subprocess.Popen( args=self._get_popen_args(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self._get_env(), - **additional_popen_kwargs ) except Exception as e: sys.stderr.write('Error executing: %s\n' % self) @@ -187,8 +203,85 @@ class WindowsCommand(BaseCommand): sys.stdout.flush() -# Set the Command class to the OS-specific version. -if utils.IsWindows(): - Command = WindowsCommand -else: - Command = PosixCommand +class AndroidCommand(BaseCommand): + def __init__(self, shell, args=None, cmd_prefix=None, timeout=60, env=None, + verbose=False, resources_func=None): + """Initialize the command and all files that need to be pushed to the + Android device. + """ + self.shell_name = os.path.basename(shell) + self.shell_dir = os.path.dirname(shell) + self.files_to_push = resources_func() + + # Make all paths in arguments relative and also prepare files from arguments + # for pushing to the device. + rel_args = [] + find_path_re = re.compile(r'.*(%s/[^\'"]+).*' % re.escape(BASE_DIR)) + for arg in (args or []): + match = find_path_re.match(arg) + if match: + self.files_to_push.append(match.group(1)) + rel_args.append( + re.sub(r'(.*)%s/(.*)' % re.escape(BASE_DIR), r'\1\2', arg)) + + super(AndroidCommand, self).__init__( + shell, args=rel_args, cmd_prefix=cmd_prefix, timeout=timeout, env=env, + verbose=verbose) + + def execute(self, **additional_popen_kwargs): + """Execute the command on the device. + + This pushes all required files to the device and then runs the command. + """ + if self.verbose: + print '# %s' % self + + android_driver().push_executable(self.shell_dir, 'bin', self.shell_name) + + for abs_file in self.files_to_push: + abs_dir = os.path.dirname(abs_file) + file_name = os.path.basename(abs_file) + rel_dir = os.path.relpath(abs_dir, BASE_DIR) + android_driver().push_file(abs_dir, file_name, rel_dir) + + start_time = time.time() + return_code = 0 + timed_out = False + try: + stdout = android_driver().run( + 'bin', self.shell_name, self.args, '.', self.timeout, self.env) + except CommandFailedException as e: + return_code = e.status + stdout = e.output + except TimeoutException as e: + return_code = 1 + timed_out = True + # Sadly the Android driver doesn't provide output on timeout. + stdout = '' + + duration = time.time() - start_time + return output.Output( + return_code, + timed_out, + stdout, + '', # No stderr available. + -1, # No pid available. + duration, + ) + + +Command = None +def setup(target_os): + """Set the Command class to the OS-specific version.""" + global Command + if target_os == 'android': + Command = AndroidCommand + elif target_os == 'windows': + Command = WindowsCommand + else: + Command = PosixCommand + +def tear_down(): + """Clean up after using commands.""" + if Command == AndroidCommand: + android_driver().tear_down() |