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