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

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

Issue 222873002: Remove pyauto tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: sync Created 6 years, 8 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
(Empty)
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
5
6 """Start and stop Web Page Replay.
7
8 Of the public module names, the following one is key:
9 ReplayServer: a class to start/stop Web Page Replay.
10 """
11
12 import logging
13 import os
14 import re
15 import signal
16 import subprocess
17 import sys
18 import time
19 import urllib
20
21
22 _CHROME_SRC_DIR = os.path.abspath(os.path.join(
23 os.path.dirname(__file__), os.pardir, os.pardir, os.pardir))
24 REPLAY_DIR = os.path.join(
25 _CHROME_SRC_DIR, 'third_party', 'webpagereplay')
26 LOG_PATH = os.path.join(
27 _CHROME_SRC_DIR, 'webpagereplay_logs', 'logs.txt')
28
29
30 # Chrome options to make it work with Web Page Replay.
31 def GetChromeFlags(replay_host, http_port, https_port):
32 assert replay_host and http_port and https_port, 'All arguments required'
33 return [
34 '--host-resolver-rules=MAP * %s,EXCLUDE localhost' % replay_host,
35 '--testing-fixed-http-port=%s' % http_port,
36 '--testing-fixed-https-port=%s' % https_port,
37 '--ignore-certificate-errors',
38 ]
39
40
41 # Signal masks on Linux are inherited from parent processes. If anything
42 # invoking us accidentally masks SIGINT (e.g. by putting a process in the
43 # background from a shell script), sending a SIGINT to the child will fail
44 # to terminate it. Running this signal handler before execing should fix that
45 # problem.
46 def ResetInterruptHandler():
47 signal.signal(signal.SIGINT, signal.SIG_DFL)
48
49
50 class ReplayError(Exception):
51 """Catch-all exception for the module."""
52 pass
53
54
55 class ReplayNotFoundError(ReplayError):
56 def __init__(self, label, path):
57 self.args = (label, path)
58
59 def __str__(self):
60 label, path = self.args
61 return 'Path does not exist for %s: %s' % (label, path)
62
63
64 class ReplayNotStartedError(ReplayError):
65 pass
66
67
68 class ReplayServer(object):
69 """Start and Stop Web Page Replay.
70
71 Web Page Replay is a proxy that can record and "replay" web pages with
72 simulated network characteristics -- without having to edit the pages
73 by hand. With WPR, tests can use "real" web content, and catch
74 performance issues that may result from introducing network delays and
75 bandwidth throttling.
76
77 Example:
78 with ReplayServer(archive_path):
79 self.NavigateToURL(start_url)
80 self.WaitUntil(...)
81
82 Environment Variables (for development):
83 WPR_ARCHIVE_PATH: path to alternate archive file (e.g. '/tmp/foo.wpr').
84 WPR_RECORD: if set, puts Web Page Replay in record mode instead of replay.
85 WPR_REPLAY_DIR: path to alternate Web Page Replay source.
86 """
87
88 def __init__(self, archive_path, replay_host, dns_port, http_port, https_port,
89 replay_options=None, replay_dir=None,
90 log_path=None):
91 """Initialize ReplayServer.
92
93 Args:
94 archive_path: a path to a specific WPR archive (required).
95 replay_host: the hostname to serve traffic.
96 dns_port: an integer port on which to serve DNS traffic. May be zero
97 to let the OS choose an available port. If None DNS forwarding is
98 disabled.
99 http_port: an integer port on which to serve HTTP traffic. May be zero
100 to let the OS choose an available port.
101 https_port: an integer port on which to serve HTTPS traffic. May be zero
102 to let the OS choose an available port.
103 replay_options: an iterable of options strings to forward to replay.py.
104 replay_dir: directory that has replay.py and related modules.
105 log_path: a path to a log file.
106 """
107 self.archive_path = os.environ.get('WPR_ARCHIVE_PATH', archive_path)
108 self.replay_options = list(replay_options or ())
109 self.replay_dir = os.environ.get('WPR_REPLAY_DIR', replay_dir or REPLAY_DIR)
110 self.log_path = log_path or LOG_PATH
111 self.dns_port = dns_port
112 self.http_port = http_port
113 self.https_port = https_port
114 self._replay_host = replay_host
115
116 if 'WPR_RECORD' in os.environ and '--record' not in self.replay_options:
117 self.replay_options.append('--record')
118 self.is_record_mode = '--record' in self.replay_options
119 self._AddDefaultReplayOptions()
120
121 self.replay_py = os.path.join(self.replay_dir, 'replay.py')
122
123 if self.is_record_mode:
124 self._CheckPath('archive directory', os.path.dirname(self.archive_path))
125 elif not os.path.exists(self.archive_path):
126 self._CheckPath('archive file', self.archive_path)
127 self._CheckPath('replay script', self.replay_py)
128
129 self.log_fh = None
130 self.replay_process = None
131
132 def _AddDefaultReplayOptions(self):
133 """Set WPR command-line options. Can be overridden if needed."""
134 self.replay_options = [
135 '--host', str(self._replay_host),
136 '--port', str(self.http_port),
137 '--ssl_port', str(self.https_port),
138 '--use_closest_match',
139 '--no-dns_forwarding',
140 '--log_level', 'warning'
141 ] + self.replay_options
142 if self.dns_port is not None:
143 self.replay_options.extend(['--dns_port', str(self.dns_port)])
144
145 def _CheckPath(self, label, path):
146 if not os.path.exists(path):
147 raise ReplayNotFoundError(label, path)
148
149 def _OpenLogFile(self):
150 log_dir = os.path.dirname(self.log_path)
151 if not os.path.exists(log_dir):
152 os.makedirs(log_dir)
153 return open(self.log_path, 'w')
154
155 def WaitForStart(self, timeout):
156 """Checks to see if the server is up and running."""
157 port_re = re.compile(
158 '.*?(?P<protocol>[A-Z]+) server started on (?P<host>.*):(?P<port>\d+)')
159
160 start_time = time.time()
161 elapsed_time = 0
162 while elapsed_time < timeout:
163 if self.replay_process.poll() is not None:
164 break # The process has exited.
165
166 # Read the ports from the WPR log.
167 if not self.http_port or not self.https_port or not self.dns_port:
168 for line in open(self.log_path).readlines():
169 m = port_re.match(line.strip())
170 if m:
171 if not self.http_port and m.group('protocol') == 'HTTP':
172 self.http_port = int(m.group('port'))
173 elif not self.https_port and m.group('protocol') == 'HTTPS':
174 self.https_port = int(m.group('port'))
175 elif not self.dns_port and m.group('protocol') == 'DNS':
176 self.dns_port = int(m.group('port'))
177
178 # Try to connect to the WPR ports.
179 if self.http_port and self.https_port:
180 try:
181 up_url = '%s://%s:%s/web-page-replay-generate-200'
182 http_up_url = up_url % ('http', self._replay_host, self.http_port)
183 https_up_url = up_url % ('https', self._replay_host, self.https_port)
184 if (200 == urllib.urlopen(http_up_url, None, {}).getcode() and
185 200 == urllib.urlopen(https_up_url, None, {}).getcode()):
186 return True
187 except IOError:
188 pass
189
190 poll_interval = min(max(elapsed_time / 10., .1), 5)
191 time.sleep(poll_interval)
192 elapsed_time = time.time() - start_time
193
194 return False
195
196 def StartServer(self):
197 """Start Web Page Replay and verify that it started.
198
199 Raises:
200 ReplayNotStartedError: if Replay start-up fails.
201 """
202 cmd_line = [sys.executable, self.replay_py]
203 cmd_line.extend(self.replay_options)
204 cmd_line.append(self.archive_path)
205 self.log_fh = self._OpenLogFile()
206 logging.debug('Starting Web-Page-Replay: %s', cmd_line)
207 kwargs = {'stdout': self.log_fh, 'stderr': subprocess.STDOUT}
208 if sys.platform.startswith('linux') or sys.platform == 'darwin':
209 kwargs['preexec_fn'] = ResetInterruptHandler
210 self.replay_process = subprocess.Popen(cmd_line, **kwargs)
211 if not self.WaitForStart(30):
212 log = open(self.log_path).read()
213 raise ReplayNotStartedError(
214 'Web Page Replay failed to start. Log output:\n%s' % log)
215
216 def StopServer(self):
217 """Stop Web Page Replay."""
218 if self.replay_process:
219 logging.debug('Trying to stop Web-Page-Replay gracefully')
220 try:
221 url = 'http://localhost:%s/web-page-replay-command-exit'
222 urllib.urlopen(url % self.http_port, None, {})
223 except IOError:
224 # IOError is possible because the server might exit without response.
225 pass
226
227 start_time = time.time()
228 while time.time() - start_time < 10: # Timeout after 10 seconds.
229 if self.replay_process.poll() is not None:
230 break
231 time.sleep(1)
232 else:
233 try:
234 # Use a SIGINT so that it can do graceful cleanup.
235 self.replay_process.send_signal(signal.SIGINT)
236 except: # pylint: disable=W0702
237 # On Windows, we are left with no other option than terminate().
238 if 'no-dns_forwarding' not in self.replay_options:
239 logging.warning('DNS configuration might not be restored!')
240 try:
241 self.replay_process.terminate()
242 except: # pylint: disable=W0702
243 pass
244 self.replay_process.wait()
245 if self.log_fh:
246 self.log_fh.close()
247
248 def __enter__(self):
249 """Add support for with-statement."""
250 self.StartServer()
251 return self
252
253 def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb):
254 """Add support for with-statement."""
255 self.StopServer()
OLDNEW
« no previous file with comments | « chrome/test/functional/webdriver_pages/settings.py ('k') | chrome/test/functional/webrtc_write_wsh.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698