OLD | NEW |
| (Empty) |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 import os as os | |
5 import subprocess as subprocess | |
6 import shutil | |
7 import tempfile | |
8 | |
9 from telemetry import browser_backend | |
10 from telemetry import util | |
11 | |
12 class DesktopBrowserBackend(browser_backend.BrowserBackend): | |
13 """The backend for controlling a locally-executed browser instance, on Linux, | |
14 Mac or Windows. | |
15 """ | |
16 def __init__(self, options, executable, is_content_shell): | |
17 super(DesktopBrowserBackend, self).__init__( | |
18 is_content_shell=is_content_shell, | |
19 supports_extensions=not is_content_shell, options=options) | |
20 | |
21 # Initialize fields so that an explosion during init doesn't break in Close. | |
22 self._proc = None | |
23 self._tmpdir = None | |
24 self._tmp_output_file = None | |
25 | |
26 self._executable = executable | |
27 if not self._executable: | |
28 raise Exception('Cannot create browser, no executable found!') | |
29 | |
30 if len(options.extensions_to_load) > 0 and is_content_shell: | |
31 raise browser_backend.ExtensionsNotSupportedException( | |
32 'Content shell does not support extensions.') | |
33 | |
34 self._port = util.GetAvailableLocalPort() | |
35 | |
36 args = [self._executable] | |
37 args.extend(self.GetBrowserStartupArgs()) | |
38 if not options.show_stdout: | |
39 self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0) | |
40 self._proc = subprocess.Popen( | |
41 args, stdout=self._tmp_output_file, stderr=subprocess.STDOUT) | |
42 else: | |
43 self._proc = subprocess.Popen(args) | |
44 | |
45 try: | |
46 self._WaitForBrowserToComeUp() | |
47 self._PostBrowserStartupInitialization() | |
48 except: | |
49 self.Close() | |
50 raise | |
51 | |
52 def GetBrowserStartupArgs(self): | |
53 args = super(DesktopBrowserBackend, self).GetBrowserStartupArgs() | |
54 args.append('--remote-debugging-port=%i' % self._port) | |
55 args.append('--window-size=1280,1024') | |
56 args.append('--enable-benchmarking') | |
57 if not self.options.dont_override_profile: | |
58 self._tmpdir = tempfile.mkdtemp() | |
59 args.append('--user-data-dir=%s' % self._tmpdir) | |
60 return args | |
61 | |
62 def IsBrowserRunning(self): | |
63 return self._proc.poll() == None | |
64 | |
65 def GetStandardOutput(self): | |
66 assert self._tmp_output_file, "Can't get standard output with show_stdout" | |
67 self._tmp_output_file.flush() | |
68 try: | |
69 with open(self._tmp_output_file.name) as f: | |
70 return f.read() | |
71 except IOError: | |
72 return '' | |
73 | |
74 def __del__(self): | |
75 self.Close() | |
76 | |
77 def Close(self): | |
78 super(DesktopBrowserBackend, self).Close() | |
79 | |
80 if self._proc: | |
81 | |
82 def IsClosed(): | |
83 if not self._proc: | |
84 return True | |
85 return self._proc.poll() != None | |
86 | |
87 # Try to politely shutdown, first. | |
88 self._proc.terminate() | |
89 try: | |
90 util.WaitFor(IsClosed, timeout=1) | |
91 self._proc = None | |
92 except util.TimeoutException: | |
93 pass | |
94 | |
95 # Kill it. | |
96 if not IsClosed(): | |
97 self._proc.kill() | |
98 try: | |
99 util.WaitFor(IsClosed, timeout=5) | |
100 self._proc = None | |
101 except util.TimeoutException: | |
102 self._proc = None | |
103 raise Exception('Could not shutdown the browser.') | |
104 | |
105 if self._tmpdir and os.path.exists(self._tmpdir): | |
106 shutil.rmtree(self._tmpdir, ignore_errors=True) | |
107 self._tmpdir = None | |
108 | |
109 if self._tmp_output_file: | |
110 self._tmp_output_file.close() | |
111 self._tmp_output_file = None | |
112 | |
113 def CreateForwarder(self, *port_pairs): | |
114 return DoNothingForwarder(*port_pairs) | |
115 | |
116 class DoNothingForwarder(object): | |
117 def __init__(self, *port_pairs): | |
118 self._host_port = port_pairs[0].local_port | |
119 | |
120 @property | |
121 def url(self): | |
122 assert self._host_port | |
123 return 'http://localhost:%i' % self._host_port | |
124 | |
125 def Close(self): | |
126 self._host_port = None | |
OLD | NEW |