OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Base class for running tests on a single device.""" | 5 """Base class for running tests on a single device.""" |
6 | 6 |
7 import contextlib | 7 import contextlib |
8 import httplib | 8 import httplib |
9 import logging | 9 import logging |
10 import os | 10 import os |
(...skipping 26 matching lines...) Expand all Loading... |
37 device: Tests will run on the device of this ID. | 37 device: Tests will run on the device of this ID. |
38 tool: Name of the Valgrind tool. | 38 tool: Name of the Valgrind tool. |
39 build_type: 'Release' or 'Debug'. | 39 build_type: 'Release' or 'Debug'. |
40 push_deps: If True, push all dependencies to the device. | 40 push_deps: If True, push all dependencies to the device. |
41 cleanup_test_files: Whether or not to cleanup test files on device. | 41 cleanup_test_files: Whether or not to cleanup test files on device. |
42 """ | 42 """ |
43 self.device = device | 43 self.device = device |
44 self.adb = android_commands.AndroidCommands(device=device) | 44 self.adb = android_commands.AndroidCommands(device=device) |
45 self.tool = CreateTool(tool, self.adb) | 45 self.tool = CreateTool(tool, self.adb) |
46 self._http_server = None | 46 self._http_server = None |
47 self._forwarder = None | |
48 self._forwarder_device_port = 8000 | 47 self._forwarder_device_port = 8000 |
49 self.forwarder_base_url = ('http://localhost:%d' % | 48 self.forwarder_base_url = ('http://localhost:%d' % |
50 self._forwarder_device_port) | 49 self._forwarder_device_port) |
51 self.flags = FlagChanger(self.adb) | 50 self.flags = FlagChanger(self.adb) |
52 self.flags.AddFlags(['--disable-fre']) | 51 self.flags.AddFlags(['--disable-fre']) |
53 self._spawning_server = None | 52 self._spawning_server = None |
54 self._spawner_forwarder = None | |
55 # We will allocate port for test server spawner when calling method | 53 # We will allocate port for test server spawner when calling method |
56 # LaunchChromeTestServerSpawner and allocate port for test server when | 54 # LaunchChromeTestServerSpawner and allocate port for test server when |
57 # starting it in TestServerThread. | 55 # starting it in TestServerThread. |
58 self.test_server_spawner_port = 0 | 56 self.test_server_spawner_port = 0 |
59 self.test_server_port = 0 | 57 self.test_server_port = 0 |
60 self.build_type = build_type | 58 self.build_type = build_type |
61 self._push_deps = push_deps | 59 self._push_deps = push_deps |
62 self._cleanup_test_files = cleanup_test_files | 60 self._cleanup_test_files = cleanup_test_files |
63 | 61 |
64 def _PushTestServerPortInfoToDevice(self): | 62 def _PushTestServerPortInfoToDevice(self): |
(...skipping 18 matching lines...) Expand all Loading... |
83 def InstallTestPackage(self): | 81 def InstallTestPackage(self): |
84 """Installs the test package once before all tests are run.""" | 82 """Installs the test package once before all tests are run.""" |
85 pass | 83 pass |
86 | 84 |
87 def PushDataDeps(self): | 85 def PushDataDeps(self): |
88 """Push all data deps to device once before all tests are run.""" | 86 """Push all data deps to device once before all tests are run.""" |
89 pass | 87 pass |
90 | 88 |
91 def SetUp(self): | 89 def SetUp(self): |
92 """Run once before all tests are run.""" | 90 """Run once before all tests are run.""" |
93 Forwarder.KillDevice(self.adb, self.tool) | |
94 self.InstallTestPackage() | 91 self.InstallTestPackage() |
95 push_size_before = self.adb.GetPushSizeInfo() | 92 push_size_before = self.adb.GetPushSizeInfo() |
96 if self._push_deps: | 93 if self._push_deps: |
97 logging.warning('Pushing data files to device.') | 94 logging.warning('Pushing data files to device.') |
98 self.PushDataDeps() | 95 self.PushDataDeps() |
99 push_size_after = self.adb.GetPushSizeInfo() | 96 push_size_after = self.adb.GetPushSizeInfo() |
100 logging.warning( | 97 logging.warning( |
101 'Total data: %0.3fMB' % | 98 'Total data: %0.3fMB' % |
102 ((push_size_after[0] - push_size_before[0]) / float(2 ** 20))) | 99 ((push_size_after[0] - push_size_before[0]) / float(2 ** 20))) |
103 logging.warning( | 100 logging.warning( |
(...skipping 17 matching lines...) Expand all Loading... |
121 port: port on which we want to the http server bind. | 118 port: port on which we want to the http server bind. |
122 extra_config_contents: Extra config contents for the HTTP server. | 119 extra_config_contents: Extra config contents for the HTTP server. |
123 """ | 120 """ |
124 self._http_server = lighttpd_server.LighttpdServer( | 121 self._http_server = lighttpd_server.LighttpdServer( |
125 document_root, port=port, extra_config_contents=extra_config_contents) | 122 document_root, port=port, extra_config_contents=extra_config_contents) |
126 if self._http_server.StartupHttpServer(): | 123 if self._http_server.StartupHttpServer(): |
127 logging.info('http server started: http://localhost:%s', | 124 logging.info('http server started: http://localhost:%s', |
128 self._http_server.port) | 125 self._http_server.port) |
129 else: | 126 else: |
130 logging.critical('Failed to start http server') | 127 logging.critical('Failed to start http server') |
131 self.StartForwarderForHttpServer() | 128 self._ForwardPortsForHttpServer() |
132 return (self._forwarder_device_port, self._http_server.port) | 129 return (self._forwarder_device_port, self._http_server.port) |
133 | 130 |
134 def _ForwardPort(self, port_pairs): | 131 def _ForwardPorts(self, port_pairs): |
135 """Creates a forwarder instance if needed and forward a port.""" | 132 """Forwards a port.""" |
136 if not self._forwarder: | 133 Forwarder.Map(port_pairs, self.adb, self.build_type, self.tool) |
137 self._forwarder = Forwarder(self.adb, self.build_type) | |
138 self._forwarder.Run(port_pairs, self.tool) | |
139 | 134 |
| 135 def _UnmapPorts(self, port_pairs): |
| 136 """Unmap previously forwarded ports.""" |
| 137 for (device_port, _) in port_pairs: |
| 138 Forwarder.UnmapDevicePort(device_port, self.adb) |
| 139 |
| 140 # Deprecated: Use ForwardPorts instead. |
140 def StartForwarder(self, port_pairs): | 141 def StartForwarder(self, port_pairs): |
141 """Starts TCP traffic forwarding for the given |port_pairs|. | 142 """Starts TCP traffic forwarding for the given |port_pairs|. |
142 | 143 |
143 Args: | 144 Args: |
144 host_port_pairs: A list of (device_port, local_port) tuples to forward. | 145 host_port_pairs: A list of (device_port, local_port) tuples to forward. |
145 """ | 146 """ |
146 self._ForwardPort(port_pairs) | 147 self._ForwardPorts(port_pairs) |
147 | 148 |
148 def StartForwarderForHttpServer(self): | 149 def _ForwardPortsForHttpServer(self): |
149 """Starts a forwarder for the HTTP server. | 150 """Starts a forwarder for the HTTP server. |
150 | 151 |
151 The forwarder forwards HTTP requests and responses between host and device. | 152 The forwarder forwards HTTP requests and responses between host and device. |
152 """ | 153 """ |
153 self._ForwardPort([(self._forwarder_device_port, self._http_server.port)]) | 154 self._ForwardPorts([(self._forwarder_device_port, self._http_server.port)]) |
154 | 155 |
155 def RestartHttpServerForwarderIfNecessary(self): | 156 def _RestartHttpServerForwarderIfNecessary(self): |
156 """Restarts the forwarder if it's not open.""" | 157 """Restarts the forwarder if it's not open.""" |
157 # Checks to see if the http server port is being used. If not forwards the | 158 # Checks to see if the http server port is being used. If not forwards the |
158 # request. | 159 # request. |
159 # TODO(dtrainor): This is not always reliable because sometimes the port | 160 # TODO(dtrainor): This is not always reliable because sometimes the port |
160 # will be left open even after the forwarder has been killed. | 161 # will be left open even after the forwarder has been killed. |
161 if not ports.IsDevicePortUsed(self.adb, | 162 if not ports.IsDevicePortUsed(self.adb, self._forwarder_device_port): |
162 self._forwarder_device_port): | 163 self._ForwardPortsForHttpServer() |
163 self.StartForwarderForHttpServer() | |
164 | 164 |
165 def ShutdownHelperToolsForTestSuite(self): | 165 def ShutdownHelperToolsForTestSuite(self): |
166 """Shuts down the server and the forwarder.""" | 166 """Shuts down the server and the forwarder.""" |
167 # Forwarders should be killed before the actual servers they're forwarding | |
168 # to as they are clients potentially with open connections and to allow for | |
169 # proper hand-shake/shutdown. | |
170 Forwarder.KillDevice(self.adb, self.tool) | |
171 if self._forwarder: | |
172 self._forwarder.Close() | |
173 if self._http_server: | 167 if self._http_server: |
| 168 self._UnmapPorts([(self._forwarder_device_port, self._http_server.port)]) |
174 self._http_server.ShutdownHttpServer() | 169 self._http_server.ShutdownHttpServer() |
175 if self._spawning_server: | 170 if self._spawning_server: |
176 self._spawning_server.Stop() | 171 self._spawning_server.Stop() |
177 self.flags.Restore() | 172 self.flags.Restore() |
178 | 173 |
179 def CleanupSpawningServerState(self): | 174 def CleanupSpawningServerState(self): |
180 """Tells the spawning server to clean up any state. | 175 """Tells the spawning server to clean up any state. |
181 | 176 |
182 If the spawning server is reused for multiple tests, this should be called | 177 If the spawning server is reused for multiple tests, this should be called |
183 after each test to prevent tests affecting each other. | 178 after each test to prevent tests affecting each other. |
184 """ | 179 """ |
185 if self._spawning_server: | 180 if self._spawning_server: |
186 self._spawning_server.CleanupState() | 181 self._spawning_server.CleanupState() |
187 | 182 |
188 def LaunchChromeTestServerSpawner(self): | 183 def LaunchChromeTestServerSpawner(self): |
189 """Launches test server spawner.""" | 184 """Launches test server spawner.""" |
190 server_ready = False | 185 server_ready = False |
191 error_msgs = [] | 186 error_msgs = [] |
192 # TODO(pliard): deflake this function. The for loop should be removed as | 187 # TODO(pliard): deflake this function. The for loop should be removed as |
193 # well as IsHttpServerConnectable(). spawning_server.Start() should also | 188 # well as IsHttpServerConnectable(). spawning_server.Start() should also |
194 # block until the server is ready. | 189 # block until the server is ready. |
195 # Try 3 times to launch test spawner server. | 190 # Try 3 times to launch test spawner server. |
196 for i in xrange(0, 3): | 191 for i in xrange(0, 3): |
197 self.test_server_spawner_port = ports.AllocateTestServerPort() | 192 self.test_server_spawner_port = ports.AllocateTestServerPort() |
198 self._ForwardPort( | 193 self._ForwardPorts( |
199 [(self.test_server_spawner_port, self.test_server_spawner_port)]) | 194 [(self.test_server_spawner_port, self.test_server_spawner_port)]) |
200 self._spawning_server = SpawningServer(self.test_server_spawner_port, | 195 self._spawning_server = SpawningServer(self.test_server_spawner_port, |
201 self.adb, | 196 self.adb, |
202 self.tool, | 197 self.tool, |
203 self._forwarder, | |
204 self.build_type) | 198 self.build_type) |
205 self._spawning_server.Start() | 199 self._spawning_server.Start() |
206 server_ready, error_msg = ports.IsHttpServerConnectable( | 200 server_ready, error_msg = ports.IsHttpServerConnectable( |
207 '127.0.0.1', self.test_server_spawner_port, path='/ping', | 201 '127.0.0.1', self.test_server_spawner_port, path='/ping', |
208 expected_read='ready') | 202 expected_read='ready') |
209 if server_ready: | 203 if server_ready: |
210 break | 204 break |
211 else: | 205 else: |
212 error_msgs.append(error_msg) | 206 error_msgs.append(error_msg) |
213 self._spawning_server.Stop() | 207 self._spawning_server.Stop() |
214 # Wait for 2 seconds then restart. | 208 # Wait for 2 seconds then restart. |
215 time.sleep(2) | 209 time.sleep(2) |
216 if not server_ready: | 210 if not server_ready: |
217 logging.error(';'.join(error_msgs)) | 211 logging.error(';'.join(error_msgs)) |
218 raise Exception('Can not start the test spawner server.') | 212 raise Exception('Can not start the test spawner server.') |
219 self._PushTestServerPortInfoToDevice() | 213 self._PushTestServerPortInfoToDevice() |
OLD | NEW |