OLD | NEW |
(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 import logging |
| 9 import optparse |
| 10 import os |
| 11 import shutil |
| 12 import signal |
| 13 import subprocess |
| 14 import sys |
| 15 import tempfile |
| 16 import time |
| 17 import urllib |
| 18 |
| 19 |
| 20 USAGE = '%s [options] CHROME_EXE TEST_NAME' % os.path.basename(sys.argv[0]) |
| 21 USER_DATA_DIR = '{TEMP}/webpagereplay_utils-chrome' |
| 22 |
| 23 # The port numbers must match those in chrome/test/perf/page_cycler_test.cc. |
| 24 HTTP_PORT = 8080 |
| 25 HTTPS_PORT = 8413 |
| 26 REPLAY_HOST='127.0.0.1' |
| 27 |
| 28 |
| 29 class ReplayError(Exception): |
| 30 """Catch-all exception for the module.""" |
| 31 pass |
| 32 |
| 33 class ReplayNotFoundError(ReplayError): |
| 34 pass |
| 35 |
| 36 class ReplayNotStartedError(ReplayError): |
| 37 pass |
| 38 |
| 39 |
| 40 class ReplayServer(object): |
| 41 """Start and Stop Web Page Replay. |
| 42 |
| 43 Example: |
| 44 with ReplayServer(replay_dir, archive_path, log_dir, replay_options): |
| 45 self.NavigateToURL(start_url) |
| 46 self.WaitUntil(...) |
| 47 """ |
| 48 LOG_FILE = 'log.txt' |
| 49 |
| 50 def __init__(self, replay_dir, archive_path, log_dir, replay_options=None): |
| 51 """Initialize ReplayServer. |
| 52 |
| 53 Args: |
| 54 replay_dir: directory that has replay.py and related modules. |
| 55 archive_path: either a directory that contains WPR archives or, |
| 56 a path to a specific WPR archive. |
| 57 log_dir: where to write log.txt. |
| 58 replay_options: a list of options strings to forward to replay.py. |
| 59 """ |
| 60 self.replay_dir = replay_dir |
| 61 self.archive_path = archive_path |
| 62 self.log_dir = log_dir |
| 63 self.replay_options = replay_options if replay_options else [] |
| 64 |
| 65 self.log_name = os.path.join(self.log_dir, self.LOG_FILE) |
| 66 self.log_fh = None |
| 67 self.replay_process = None |
| 68 |
| 69 self.wpr_py = os.path.join(self.replay_dir, 'replay.py') |
| 70 if not os.path.exists(self.wpr_py): |
| 71 raise ReplayNotFoundError('Path does not exist: %s' % self.wpr_py) |
| 72 self.wpr_options = [ |
| 73 '--port', str(HTTP_PORT), |
| 74 '--ssl_port', str(HTTPS_PORT), |
| 75 '--use_closest_match', |
| 76 # TODO(slamm): Add traffic shaping (requires root): |
| 77 # '--net', 'fios', |
| 78 ] |
| 79 self.wpr_options.extend(self.replay_options) |
| 80 |
| 81 def _OpenLogFile(self): |
| 82 if not os.path.exists(self.log_dir): |
| 83 os.makedirs(self.log_dir) |
| 84 return open(self.log_name, 'w') |
| 85 |
| 86 def IsStarted(self): |
| 87 """Checks to see if the server is up and running.""" |
| 88 for _ in range(5): |
| 89 if self.replay_process.poll() is not None: |
| 90 # The process has exited. |
| 91 break |
| 92 try: |
| 93 up_url = '%s://localhost:%s/web-page-replay-generate-200' |
| 94 http_up_url = up_url % ('http', HTTP_PORT) |
| 95 https_up_url = up_url % ('https', HTTPS_PORT) |
| 96 if (200 == urllib.urlopen(http_up_url, None, {}).getcode() and |
| 97 200 == urllib.urlopen(https_up_url, None, {}).getcode()): |
| 98 return True |
| 99 except IOError: |
| 100 time.sleep(1) |
| 101 return False |
| 102 |
| 103 def StartServer(self): |
| 104 """Start Web Page Replay and verify that it started. |
| 105 |
| 106 Raises: |
| 107 ReplayNotStartedError if Replay start-up fails. |
| 108 """ |
| 109 cmd_line = [self.wpr_py] |
| 110 cmd_line.extend(self.wpr_options) |
| 111 cmd_line.append(self.archive_path) |
| 112 self.log_fh = self._OpenLogFile() |
| 113 logging.debug('Starting Web-Page-Replay: %s', cmd_line) |
| 114 self.replay_process = subprocess.Popen( |
| 115 cmd_line, stdout=self.log_fh, stderr=subprocess.STDOUT) |
| 116 if not self.IsStarted(): |
| 117 raise ReplayNotStartedError( |
| 118 'Web Page Replay failed to start. See the log file: ' + self.log_name) |
| 119 |
| 120 def StopServer(self): |
| 121 """Stop Web Page Replay.""" |
| 122 if self.replay_process: |
| 123 logging.debug('Stopping Web-Page-Replay') |
| 124 # Use a SIGINT here so that it can do graceful cleanup. |
| 125 # Otherwise, we will leave subprocesses hanging. |
| 126 self.replay_process.send_signal(signal.SIGINT) |
| 127 self.replay_process.wait() |
| 128 if self.log_fh: |
| 129 self.log_fh.close() |
| 130 |
| 131 def __enter__(self): |
| 132 """Add support for with-statement.""" |
| 133 self.StartServer() |
| 134 |
| 135 def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb): |
| 136 """Add support for with-statement.""" |
| 137 self.StopServer() |
OLD | NEW |