| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import subprocess | 5 import subprocess |
| 6 import threading |
| 6 | 7 |
| 7 from devtoolslib.shell import Shell | 8 from devtoolslib.shell import Shell |
| 8 from devtoolslib import http_server | 9 from devtoolslib import http_server |
| 9 | 10 |
| 10 | 11 |
| 11 class LinuxShell(Shell): | 12 class LinuxShell(Shell): |
| 12 """Wrapper around Mojo shell running on Linux. | 13 """Wrapper around Mojo shell running on Linux. |
| 13 | 14 |
| 14 Args: | 15 Args: |
| 15 executable_path: path to the shell binary | 16 executable_path: path to the shell binary |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 """Runs the shell with given arguments until shell exits, passing the stdout | 55 """Runs the shell with given arguments until shell exits, passing the stdout |
| 55 mingled with stderr produced by the shell onto the stdout. | 56 mingled with stderr produced by the shell onto the stdout. |
| 56 | 57 |
| 57 Returns: | 58 Returns: |
| 58 Exit code retured by the shell or None if the exit code cannot be | 59 Exit code retured by the shell or None if the exit code cannot be |
| 59 retrieved. | 60 retrieved. |
| 60 """ | 61 """ |
| 61 command = self.command_prefix + [self.executable_path] + arguments | 62 command = self.command_prefix + [self.executable_path] + arguments |
| 62 return subprocess.call(command, stderr=subprocess.STDOUT) | 63 return subprocess.call(command, stderr=subprocess.STDOUT) |
| 63 | 64 |
| 64 def RunAndGetOutput(self, arguments): | 65 def RunAndGetOutput(self, arguments, timeout=None): |
| 65 """Runs the shell with given arguments until shell exits. | 66 """Runs the shell with given arguments until shell exits and returns the |
| 67 output. |
| 66 | 68 |
| 67 Args: | 69 Args: |
| 68 arguments: list of arguments for the shell | 70 arguments: list of arguments for the shell |
| 71 timeout: maximum running time in seconds, after which the shell will be |
| 72 terminated |
| 69 | 73 |
| 70 Returns: | 74 Returns: |
| 71 A tuple of (return_code, output). |return_code| is the exit code returned | 75 A tuple of (return_code, output, did_time_out). |return_code| is the exit |
| 72 by the shell or None if the exit code cannot be retrieved. |output| is the | 76 code returned by the shell or None if the exit code cannot be retrieved. |
| 73 stdout mingled with the stderr produced by the shell. | 77 |output| is the stdout mingled with the stderr produced by the shell. |
| 78 |did_time_out| is True iff the shell was terminated because it exceeded |
| 79 the |timeout| and False otherwise. |
| 74 """ | 80 """ |
| 75 command = self.command_prefix + [self.executable_path] + arguments | 81 command = self.command_prefix + [self.executable_path] + arguments |
| 76 p = subprocess.Popen(command, stdout=subprocess.PIPE, | 82 p = subprocess.Popen(command, stdout=subprocess.PIPE, |
| 77 stderr=subprocess.STDOUT) | 83 stderr=subprocess.STDOUT) |
| 78 (output, _) = p.communicate() | 84 |
| 79 return p.returncode, output | 85 class Results: |
| 86 """Workaround for Python scoping rules that prevent assigning to variables |
| 87 from the outer scope. |
| 88 """ |
| 89 output = None |
| 90 |
| 91 def do_run(): |
| 92 (Results.output, _) = p.communicate() |
| 93 |
| 94 run_thread = threading.Thread(target=do_run) |
| 95 run_thread.start() |
| 96 run_thread.join(timeout) |
| 97 |
| 98 if run_thread.is_alive(): |
| 99 p.terminate() |
| 100 return p.returncode, Results.output, True |
| 101 return p.returncode, Results.output, False |
| OLD | NEW |