Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py

Issue 2859703002: webkitpy: Override TEMPDIR for Xvfb. (Closed)
Patch Set: track mock call env, add test Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_win_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (C) 2011 Google Inc. All rights reserved. 1 # Copyright (C) 2011 Google Inc. All rights reserved.
2 # 2 #
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer 10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the 11 # in the documentation and/or other materials provided with the
12 # distribution. 12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its 13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from 14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission. 15 # this software without specific prior written permission.
16 # 16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import collections
29 import logging 30 import logging
30 import os 31 import os
31 import StringIO 32 import StringIO
32 33
33 from webkitpy.common.system.executive import ScriptError 34 from webkitpy.common.system.executive import ScriptError
34 35
35 _log = logging.getLogger(__name__) 36 _log = logging.getLogger(__name__)
36 37
37 38
38 class MockProcess(object): 39 class MockProcess(object):
(...skipping 14 matching lines...) Expand all
53 return None 54 return None
54 return self.returncode 55 return self.returncode
55 56
56 def communicate(self, *_): 57 def communicate(self, *_):
57 return (self.stdout.getvalue(), self.stderr.getvalue()) 58 return (self.stdout.getvalue(), self.stderr.getvalue())
58 59
59 def kill(self): 60 def kill(self):
60 return 61 return
61 62
62 63
64 MockCall = collections.namedtuple('MockCall', ('args', 'env'))
65
66
63 class MockExecutive(object): 67 class MockExecutive(object):
64 PIPE = 'MOCK PIPE' 68 PIPE = 'MOCK PIPE'
65 STDOUT = 'MOCK STDOUT' 69 STDOUT = 'MOCK STDOUT'
66 DEVNULL = 'MOCK_DEVNULL' 70 DEVNULL = 'MOCK_DEVNULL'
67 71
68 @staticmethod 72 @staticmethod
69 def ignore_error(error): 73 def ignore_error(error):
70 pass 74 pass
71 75
72 def __init__(self, should_log=False, should_throw=False, 76 def __init__(self, should_log=False, should_throw=False,
73 output='MOCK output of child process', stderr='', 77 output='MOCK output of child process', stderr='',
74 exit_code=0, exception=None, run_command_fn=None): 78 exit_code=0, exception=None, run_command_fn=None):
75 self._should_log = should_log 79 self._should_log = should_log
76 self._should_throw = should_throw 80 self._should_throw = should_throw
77 # FIXME: Once executive wraps os.getpid() we can just use a static pid f or "this" process. 81 # FIXME: Once executive wraps os.getpid() we can just use a static pid f or "this" process.
78 self._running_pids = {'test-webkitpy': os.getpid()} 82 self._running_pids = {'test-webkitpy': os.getpid()}
79 self._output = output 83 self._output = output
80 self._stderr = stderr 84 self._stderr = stderr
81 self._exit_code = exit_code 85 self._exit_code = exit_code
82 self._exception = exception 86 self._exception = exception
83 self._run_command_fn = run_command_fn 87 self._run_command_fn = run_command_fn
84 self._proc = None 88 self._proc = None
85 self.calls = [] 89 self.full_calls = []
90
91 def _append_call(self, args, env=None):
92 if env:
93 env = env.copy()
94 self.full_calls.append(MockCall(
95 args=args,
96 env=env.copy() if env is not None else None,
97 ))
86 98
87 def check_running_pid(self, pid): 99 def check_running_pid(self, pid):
88 return pid in self._running_pids.values() 100 return pid in self._running_pids.values()
89 101
90 def running_pids(self, process_name_filter): 102 def running_pids(self, process_name_filter):
91 running_pids = [] 103 running_pids = []
92 for process_name, process_pid in self._running_pids.iteritems(): 104 for process_name, process_pid in self._running_pids.iteritems():
93 if process_name_filter(process_name): 105 if process_name_filter(process_name):
94 running_pids.append(process_pid) 106 running_pids.append(process_pid)
95 107
(...skipping 10 matching lines...) Expand all
106 args, 118 args,
107 cwd=None, 119 cwd=None,
108 input=None, # pylint: disable=redefined-builtin 120 input=None, # pylint: disable=redefined-builtin
109 timeout_seconds=False, 121 timeout_seconds=False,
110 error_handler=None, 122 error_handler=None,
111 return_exit_code=False, 123 return_exit_code=False,
112 return_stderr=True, 124 return_stderr=True,
113 decode_output=False, 125 decode_output=False,
114 env=None, 126 env=None,
115 debug_logging=False): 127 debug_logging=False):
116 self.calls.append(args) 128 self._append_call(args, env=env)
117 129
118 assert isinstance(args, list) or isinstance(args, tuple) 130 assert isinstance(args, list) or isinstance(args, tuple)
119 131
120 if self._should_log: 132 if self._should_log:
121 env_string = '' 133 env_string = ''
122 if env: 134 if env:
123 env_string = ', env=%s' % env 135 env_string = ', env=%s' % env
124 input_string = '' 136 input_string = ''
125 if input: 137 if input:
126 input_string = ', input=%s' % input 138 input_string = ', input=%s' % input
(...skipping 26 matching lines...) Expand all
153 pass 165 pass
154 166
155 def kill_process(self, pid): 167 def kill_process(self, pid):
156 pass 168 pass
157 169
158 def interrupt(self, pid): 170 def interrupt(self, pid):
159 pass 171 pass
160 172
161 def popen(self, args, cwd=None, env=None, **_): 173 def popen(self, args, cwd=None, env=None, **_):
162 assert all(isinstance(arg, basestring) for arg in args) 174 assert all(isinstance(arg, basestring) for arg in args)
163 self.calls.append(args) 175 self._append_call(args, env=env)
164 if self._should_log: 176 if self._should_log:
165 cwd_string = '' 177 cwd_string = ''
166 if cwd: 178 if cwd:
167 cwd_string = ', cwd=%s' % cwd 179 cwd_string = ', cwd=%s' % cwd
168 env_string = '' 180 env_string = ''
169 if env: 181 if env:
170 env_string = ', env=%s' % env 182 env_string = ', env=%s' % env
171 _log.info('MOCK popen: %s%s%s', args, cwd_string, env_string) 183 _log.info('MOCK popen: %s%s%s', args, cwd_string, env_string)
172 if not self._proc: 184 if not self._proc:
173 self._proc = MockProcess(self._output) 185 self._proc = MockProcess(self._output)
174 return self._proc 186 return self._proc
175 187
176 def call(self, args, **_): 188 def call(self, args, **_):
177 assert all(isinstance(arg, basestring) for arg in args) 189 assert all(isinstance(arg, basestring) for arg in args)
178 self.calls.append(args) 190 self._append_call(args)
179 _log.info('Mock call: %s', args) 191 _log.info('Mock call: %s', args)
180 192
181 def run_in_parallel(self, commands): 193 def run_in_parallel(self, commands):
182 assert len(commands) 194 assert len(commands)
183 195
184 num_previous_calls = len(self.calls) 196 num_previous_calls = len(self.full_calls)
185 command_outputs = [] 197 command_outputs = []
186 for cmd_line, cwd in commands: 198 for cmd_line, cwd in commands:
187 assert all(isinstance(arg, basestring) for arg in cmd_line) 199 assert all(isinstance(arg, basestring) for arg in cmd_line)
188 command_outputs.append([0, self.run_command(cmd_line, cwd=cwd), '']) 200 command_outputs.append([0, self.run_command(cmd_line, cwd=cwd), ''])
189 201
190 new_calls = self.calls[num_previous_calls:] 202 new_calls = self.full_calls[num_previous_calls:]
191 self.calls = self.calls[:num_previous_calls] 203 self.full_calls = self.full_calls[:num_previous_calls]
192 self.calls.append(new_calls) 204 self.full_calls.append(new_calls)
193 return command_outputs 205 return command_outputs
194 206
195 def map(self, thunk, arglist, processes=None): 207 def map(self, thunk, arglist, processes=None):
196 return map(thunk, arglist) 208 return map(thunk, arglist)
197 209
198 def process_dump(self): 210 def process_dump(self):
199 return [] 211 return []
200 212
213 @property
214 def calls(self):
215 def get_args(v):
216 if isinstance(v, list):
217 return [get_args(e) for e in v]
218 elif isinstance(v, MockCall):
219 return v.args
220 else:
221 return TypeError('Unknown full_calls type: %s' % (type(v).__name __,))
222 return get_args(self.full_calls)
Dirk Pranke 2017/05/04 00:05:48 Can't this just be: @property def calls(self)
dnj 2017/05/04 00:20:37 No, b/c "run_in_parallel" adds lists of MockCall t
Dirk Pranke 2017/05/04 00:43:46 Ah, I see. That's ugly. Can you add a TODO and/or
dnj 2017/05/04 16:07:54 Done.
223
201 224
202 def mock_git_commands(vals, strict=False): 225 def mock_git_commands(vals, strict=False):
203 def run_fn(args): 226 def run_fn(args):
204 sub_command = args[1] 227 sub_command = args[1]
205 if strict and sub_command not in vals: 228 if strict and sub_command not in vals:
206 raise AssertionError('{} not found in sub-command list {}'.format( 229 raise AssertionError('{} not found in sub-command list {}'.format(
207 sub_command, vals)) 230 sub_command, vals))
208 return vals.get(sub_command, '') 231 return vals.get(sub_command, '')
209 return MockExecutive(run_command_fn=run_fn) 232 return MockExecutive(run_command_fn=run_fn)
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_win_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698