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

Side by Side Diff: chrome/test/functional/webpagereplay.py

Issue 23455009: Use exit command to stop web page replay server. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comment and roll webpagereplay to r520. Created 7 years, 3 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Start and stop Web Page Replay. 6 """Start and stop Web Page Replay.
7 7
8 Of the public module names, the following one is key: 8 Of the public module names, the following one is key:
9 ReplayServer: a class to start/stop Web Page Replay. 9 ReplayServer: a class to start/stop Web Page Replay.
10 """ 10 """
(...skipping 17 matching lines...) Expand all
28 28
29 # Chrome options to make it work with Web Page Replay. 29 # Chrome options to make it work with Web Page Replay.
30 def GetChromeFlags(replay_host, http_port, https_port): 30 def GetChromeFlags(replay_host, http_port, https_port):
31 return [ 31 return [
32 '--host-resolver-rules=MAP * %s,EXCLUDE localhost' % replay_host, 32 '--host-resolver-rules=MAP * %s,EXCLUDE localhost' % replay_host,
33 '--testing-fixed-http-port=%s' % http_port, 33 '--testing-fixed-http-port=%s' % http_port,
34 '--testing-fixed-https-port=%s' % https_port, 34 '--testing-fixed-https-port=%s' % https_port,
35 '--ignore-certificate-errors', 35 '--ignore-certificate-errors',
36 ] 36 ]
37 37
38
38 # Signal masks on Linux are inherited from parent processes. If anything 39 # Signal masks on Linux are inherited from parent processes. If anything
39 # invoking us accidentally masks SIGINT (e.g. by putting a process in the 40 # invoking us accidentally masks SIGINT (e.g. by putting a process in the
40 # background from a shell script), sending a SIGINT to the child will fail 41 # background from a shell script), sending a SIGINT to the child will fail
41 # to terminate it. Running this signal handler before execing should fix that 42 # to terminate it. Running this signal handler before execing should fix that
42 # problem. 43 # problem.
43 def ResetInterruptHandler(): 44 def ResetInterruptHandler():
44 signal.signal(signal.SIGINT, signal.SIG_DFL) 45 signal.signal(signal.SIGINT, signal.SIG_DFL)
45 46
47
46 class ReplayError(Exception): 48 class ReplayError(Exception):
47 """Catch-all exception for the module.""" 49 """Catch-all exception for the module."""
48 pass 50 pass
49 51
52
50 class ReplayNotFoundError(ReplayError): 53 class ReplayNotFoundError(ReplayError):
51 def __init__(self, label, path): 54 def __init__(self, label, path):
52 self.args = (label, path) 55 self.args = (label, path)
53 56
54 def __str__(self): 57 def __str__(self):
55 label, path = self.args 58 label, path = self.args
56 return 'Path does not exist for %s: %s' % (label, path) 59 return 'Path does not exist for %s: %s' % (label, path)
57 60
61
58 class ReplayNotStartedError(ReplayError): 62 class ReplayNotStartedError(ReplayError):
59 pass 63 pass
60 64
61 65
62 class ReplayServer(object): 66 class ReplayServer(object):
63 """Start and Stop Web Page Replay. 67 """Start and Stop Web Page Replay.
64 68
65 Web Page Replay is a proxy that can record and "replay" web pages with 69 Web Page Replay is a proxy that can record and "replay" web pages with
66 simulated network characteristics -- without having to edit the pages 70 simulated network characteristics -- without having to edit the pages
67 by hand. With WPR, tests can use "real" web content, and catch 71 by hand. With WPR, tests can use "real" web content, and catch
68 performance issues that may result from introducing network delays and 72 performance issues that may result from introducing network delays and
69 bandwidth throttling. 73 bandwidth throttling.
70 74
71 Example: 75 Example:
72 with ReplayServer(archive_path): 76 with ReplayServer(archive_path):
73 self.NavigateToURL(start_url) 77 self.NavigateToURL(start_url)
74 self.WaitUntil(...) 78 self.WaitUntil(...)
75 79
76 Environment Variables (for development): 80 Environment Variables (for development):
77 WPR_ARCHIVE_PATH: path to alternate archive file (e.g. '/tmp/foo.wpr'). 81 WPR_ARCHIVE_PATH: path to alternate archive file (e.g. '/tmp/foo.wpr').
78 WPR_RECORD: if set, puts Web Page Replay in record mode instead of replay. 82 WPR_RECORD: if set, puts Web Page Replay in record mode instead of replay.
79 WPR_REPLAY_DIR: path to alternate Web Page Replay source. 83 WPR_REPLAY_DIR: path to alternate Web Page Replay source.
80 """ 84 """
85
81 def __init__(self, archive_path, replay_host, http_port, https_port, 86 def __init__(self, archive_path, replay_host, http_port, https_port,
82 replay_options=None, replay_dir=None, 87 replay_options=None, replay_dir=None,
83 log_path=None): 88 log_path=None):
84 """Initialize ReplayServer. 89 """Initialize ReplayServer.
85 90
86 Args: 91 Args:
87 archive_path: a path to a specific WPR archive (required). 92 archive_path: a path to a specific WPR archive (required).
88 replay_options: an iterable of options strings to forward to replay.py. 93 replay_options: an iterable of options strings to forward to replay.py.
89 replay_dir: directory that has replay.py and related modules. 94 replay_dir: directory that has replay.py and related modules.
90 log_path: a path to a log file. 95 log_path: a path to a log file.
91 """ 96 """
92 self.archive_path = os.environ.get('WPR_ARCHIVE_PATH', archive_path) 97 self.archive_path = os.environ.get('WPR_ARCHIVE_PATH', archive_path)
93 self.replay_options = list(replay_options or ()) 98 self.replay_options = list(replay_options or ())
94 self.replay_dir = os.environ.get('WPR_REPLAY_DIR', replay_dir or REPLAY_DIR) 99 self.replay_dir = os.environ.get('WPR_REPLAY_DIR', replay_dir or REPLAY_DIR)
95 self.log_path = log_path or LOG_PATH 100 self.log_path = log_path or LOG_PATH
96 self._http_port = http_port 101 self._http_port = http_port
97 self._https_port = https_port 102 self._https_port = https_port
98 self._replay_host = replay_host 103 self._replay_host = replay_host
99 104
100 if 'WPR_RECORD' in os.environ and '--record' not in self.replay_options: 105 if 'WPR_RECORD' in os.environ and '--record' not in self.replay_options:
101 self.replay_options.append('--record') 106 self.replay_options.append('--record')
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 200 == urllib.urlopen(https_up_url, None, {}).getcode()): 152 200 == urllib.urlopen(https_up_url, None, {}).getcode()):
148 return True 153 return True
149 except IOError: 154 except IOError:
150 time.sleep(1) 155 time.sleep(1)
151 return False 156 return False
152 157
153 def StartServer(self): 158 def StartServer(self):
154 """Start Web Page Replay and verify that it started. 159 """Start Web Page Replay and verify that it started.
155 160
156 Raises: 161 Raises:
157 ReplayNotStartedError if Replay start-up fails. 162 ReplayNotStartedError: if Replay start-up fails.
158 """ 163 """
159 cmd_line = [sys.executable, self.replay_py] 164 cmd_line = [sys.executable, self.replay_py]
160 cmd_line.extend(self.replay_options) 165 cmd_line.extend(self.replay_options)
161 cmd_line.append(self.archive_path) 166 cmd_line.append(self.archive_path)
162 self.log_fh = self._OpenLogFile() 167 self.log_fh = self._OpenLogFile()
163 logging.debug('Starting Web-Page-Replay: %s', cmd_line) 168 logging.debug('Starting Web-Page-Replay: %s', cmd_line)
164 kwargs = { 'stdout': self.log_fh, 'stderr': subprocess.STDOUT } 169 kwargs = {'stdout': self.log_fh, 'stderr': subprocess.STDOUT}
165 if sys.platform.startswith('linux') or sys.platform == 'darwin': 170 if sys.platform.startswith('linux') or sys.platform == 'darwin':
166 kwargs['preexec_fn'] = ResetInterruptHandler 171 kwargs['preexec_fn'] = ResetInterruptHandler
167 self.replay_process = subprocess.Popen(cmd_line, **kwargs) 172 self.replay_process = subprocess.Popen(cmd_line, **kwargs)
168 if not self.IsStarted(): 173 if not self.IsStarted():
169 log = open(self.log_path).read() 174 log = open(self.log_path).read()
170 raise ReplayNotStartedError( 175 raise ReplayNotStartedError(
171 'Web Page Replay failed to start. Log output:\n%s' % log) 176 'Web Page Replay failed to start. Log output:\n%s' % log)
172 177
173 def StopServer(self): 178 def StopServer(self):
174 """Stop Web Page Replay.""" 179 """Stop Web Page Replay."""
175 if self.replay_process: 180 if self.replay_process:
176 logging.debug('Stopping Web-Page-Replay') 181 logging.debug('Trying to stop Web-Page-Replay gracefully')
177 # Use a SIGINT so that it can do graceful cleanup. On Windows, we are left
178 # with no other option than terminate().
179 try: 182 try:
180 self.replay_process.send_signal(signal.SIGINT) 183 url = 'http://localhost:%s/web-page-replay-command-exit'
181 except: 184 urllib.urlopen(url % self._http_port, None, {})
182 self.replay_process.terminate() 185 except IOError:
183 self.replay_process.wait() 186 # IOError is possible because the server might exit without response.
187 pass
188
189 start_time = time.time()
190 while time.time() - start_time < 10: # Timeout after 10 seconds.
191 if self.replay_process.poll() is not None:
192 break
193 time.sleep(1)
194 else:
195 try:
196 # Use a SIGINT so that it can do graceful cleanup.
197 self.replay_process.send_signal(signal.SIGINT)
198 except: # pylint: disable=W0702
199 # On Windows, we are left with no other option than terminate().
200 if 'no-dns_forwarding' not in self.replay_options:
201 logging.warning('DNS configuration might not be restored!')
202 try:
203 self.replay_process.terminate()
204 except: # pylint: disable=W0702
205 pass
206 self.replay_process.wait()
184 if self.log_fh: 207 if self.log_fh:
185 self.log_fh.close() 208 self.log_fh.close()
186 209
187 def __enter__(self): 210 def __enter__(self):
188 """Add support for with-statement.""" 211 """Add support for with-statement."""
189 self.StartServer() 212 self.StartServer()
190 return self 213 return self
191 214
192 def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb): 215 def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb):
193 """Add support for with-statement.""" 216 """Add support for with-statement."""
194 self.StopServer() 217 self.StopServer()
OLDNEW
« DEPS ('K') | « DEPS ('k') | tools/telemetry/telemetry/core/wpr_server.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698