1
# Copyright (C) 2011 Google Inc. All rights reserved.
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions are
7
# * Redistributions of source code must retain the above copyright
8
# notice, this list of conditions and the following disclaimer.
9
# * Redistributions in binary form must reproduce the above
10
# copyright notice, this list of conditions and the following disclaimer
11
# in the documentation and/or other materials provided with the
13
# * Neither the name of Google Inc. nor the names of its
14
# contributors may be used to endorse or promote products derived from
15
# this software without specific prior written permission.
17
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
from webkitpy.common.system.executive import ScriptError
35
_log = logging.getLogger(__name__)
38
class MockProcess(object):
39
def __init__(self, stdout='MOCK STDOUT\n', stderr=''):
41
self.stdout = StringIO.StringIO(stdout)
42
self.stderr = StringIO.StringIO(stderr)
43
self.stdin = StringIO.StringIO()
49
# FIXME: This should be unified with MockExecutive2
50
class MockExecutive(object):
52
STDOUT = "MOCK STDOUT"
55
def ignore_error(error):
58
def __init__(self, should_log=False, should_throw=False, should_throw_when_run=None):
59
self._should_log = should_log
60
self._should_throw = should_throw
61
self._should_throw_when_run = should_throw_when_run or set()
62
# FIXME: Once executive wraps os.getpid() we can just use a static pid for "this" process.
63
self._running_pids = {'test-webkitpy': os.getpid()}
67
def check_running_pid(self, pid):
68
return pid in self._running_pids.values()
70
def running_pids(self, process_name_filter):
72
for process_name, process_pid in self._running_pids.iteritems():
73
if process_name_filter(process_name):
74
running_pids.append(process_pid)
76
_log.info("MOCK running_pids: %s" % running_pids)
79
def run_and_throw_if_fail(self, args, quiet=False, cwd=None, env=None):
83
env_string = ", env=%s" % env
84
_log.info("MOCK run_and_throw_if_fail: %s, cwd=%s%s" % (args, cwd, env_string))
85
if self._should_throw_when_run.intersection(args):
86
raise ScriptError("Exception for %s" % args, output="MOCK command output")
87
return "MOCK output of child process"
94
return_exit_code=False,
99
self.calls.append(args)
101
assert(isinstance(args, list) or isinstance(args, tuple))
105
env_string = ", env=%s" % env
108
input_string = ", input=%s" % input
109
_log.info("MOCK run_command: %s, cwd=%s%s%s" % (args, cwd, env_string, input_string))
110
output = "MOCK output of child process"
111
if self._should_throw:
112
raise ScriptError("MOCK ScriptError", output=output)
118
def kill_all(self, process_name):
121
def kill_process(self, pid):
124
def popen(self, args, cwd=None, env=None, **kwargs):
125
self.calls.append(args)
129
cwd_string = ", cwd=%s" % cwd
132
env_string = ", env=%s" % env
133
_log.info("MOCK popen: %s%s%s" % (args, cwd_string, env_string))
135
self._proc = MockProcess()
138
def run_in_parallel(self, commands):
139
num_previous_calls = len(self.calls)
141
for cmd_line, cwd in commands:
142
command_outputs.append([0, self.run_command(cmd_line, cwd=cwd), ''])
144
new_calls = self.calls[num_previous_calls:]
145
self.calls = self.calls[:num_previous_calls]
146
self.calls.append(new_calls)
147
return command_outputs
150
class MockExecutive2(MockExecutive):
151
"""MockExecutive2 is like MockExecutive except it doesn't log anything."""
153
def __init__(self, output='', exit_code=0, exception=None, run_command_fn=None, stderr=''):
154
self._output = output
155
self._stderr = stderr
156
self._exit_code = exit_code
157
self._exception = exception
158
self._run_command_fn = run_command_fn
161
def run_command(self,
166
return_exit_code=False,
170
self.calls.append(args)
171
assert(isinstance(args, list) or isinstance(args, tuple))
173
raise self._exception # pylint: disable-msg=E0702
174
if self._run_command_fn:
175
return self._run_command_fn(args)
177
return self._exit_code
178
if self._exit_code and error_handler:
179
script_error = ScriptError(script_args=args, exit_code=self._exit_code, output=self._output)
180
error_handler(script_error)
182
return self._output + self._stderr