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 logging | 7 import logging |
8 import time | 8 import time |
9 | 9 |
10 from pylib import android_commands | |
11 from pylib import ports | 10 from pylib import ports |
12 from pylib.chrome_test_server_spawner import SpawningServer | 11 from pylib.chrome_test_server_spawner import SpawningServer |
| 12 from pylib.device import device_utils |
13 from pylib.forwarder import Forwarder | 13 from pylib.forwarder import Forwarder |
14 from pylib.valgrind_tools import CreateTool | 14 from pylib.valgrind_tools import CreateTool |
15 # TODO(frankf): Move this to pylib/utils | 15 # TODO(frankf): Move this to pylib/utils |
16 import lighttpd_server | 16 import lighttpd_server |
17 | 17 |
18 | 18 |
19 # A file on device to store ports of net test server. The format of the file is | 19 # A file on device to store ports of net test server. The format of the file is |
20 # test-spawner-server-port:test-server-port | 20 # test-spawner-server-port:test-server-port |
21 NET_TEST_SERVER_PORT_INFO_FILE = 'net-test-server-ports' | 21 NET_TEST_SERVER_PORT_INFO_FILE = 'net-test-server-ports' |
22 | 22 |
23 | 23 |
24 class BaseTestRunner(object): | 24 class BaseTestRunner(object): |
25 """Base class for running tests on a single device.""" | 25 """Base class for running tests on a single device.""" |
26 | 26 |
27 def __init__(self, device, tool, push_deps=True, cleanup_test_files=False): | 27 def __init__(self, device_serial, tool, push_deps=True, |
| 28 cleanup_test_files=False): |
28 """ | 29 """ |
29 Args: | 30 Args: |
30 device: Tests will run on the device of this ID. | 31 device: Tests will run on the device of this ID. |
31 tool: Name of the Valgrind tool. | 32 tool: Name of the Valgrind tool. |
32 push_deps: If True, push all dependencies to the device. | 33 push_deps: If True, push all dependencies to the device. |
33 cleanup_test_files: Whether or not to cleanup test files on device. | 34 cleanup_test_files: Whether or not to cleanup test files on device. |
34 """ | 35 """ |
35 self.device = device | 36 self.device_serial = device_serial |
36 self.adb = android_commands.AndroidCommands(device=device) | 37 self.device = device_utils.DeviceUtils(device_serial) |
37 self.tool = CreateTool(tool, self.adb) | 38 self.tool = CreateTool(tool, self.device) |
38 self._http_server = None | 39 self._http_server = None |
39 self._forwarder_device_port = 8000 | 40 self._forwarder_device_port = 8000 |
40 self.forwarder_base_url = ('http://localhost:%d' % | 41 self.forwarder_base_url = ('http://localhost:%d' % |
41 self._forwarder_device_port) | 42 self._forwarder_device_port) |
42 self._spawning_server = None | 43 self._spawning_server = None |
43 # We will allocate port for test server spawner when calling method | 44 # We will allocate port for test server spawner when calling method |
44 # LaunchChromeTestServerSpawner and allocate port for test server when | 45 # LaunchChromeTestServerSpawner and allocate port for test server when |
45 # starting it in TestServerThread. | 46 # starting it in TestServerThread. |
46 self.test_server_spawner_port = 0 | 47 self.test_server_spawner_port = 0 |
47 self.test_server_port = 0 | 48 self.test_server_port = 0 |
48 self._push_deps = push_deps | 49 self._push_deps = push_deps |
49 self._cleanup_test_files = cleanup_test_files | 50 self._cleanup_test_files = cleanup_test_files |
50 | 51 |
51 def _PushTestServerPortInfoToDevice(self): | 52 def _PushTestServerPortInfoToDevice(self): |
52 """Pushes the latest port information to device.""" | 53 """Pushes the latest port information to device.""" |
53 self.adb.SetFileContents(self.adb.GetExternalStorage() + '/' + | 54 self.device.old_interface.SetFileContents( |
54 NET_TEST_SERVER_PORT_INFO_FILE, | 55 self.device.old_interface.GetExternalStorage() + '/' + |
55 '%d:%d' % (self.test_server_spawner_port, | 56 NET_TEST_SERVER_PORT_INFO_FILE, |
56 self.test_server_port)) | 57 '%d:%d' % (self.test_server_spawner_port, self.test_server_port)) |
57 | 58 |
58 def RunTest(self, test): | 59 def RunTest(self, test): |
59 """Runs a test. Needs to be overridden. | 60 """Runs a test. Needs to be overridden. |
60 | 61 |
61 Args: | 62 Args: |
62 test: A test to run. | 63 test: A test to run. |
63 | 64 |
64 Returns: | 65 Returns: |
65 Tuple containing: | 66 Tuple containing: |
66 (base_test_result.TestRunResults, tests to rerun or None) | 67 (base_test_result.TestRunResults, tests to rerun or None) |
67 """ | 68 """ |
68 raise NotImplementedError | 69 raise NotImplementedError |
69 | 70 |
70 def InstallTestPackage(self): | 71 def InstallTestPackage(self): |
71 """Installs the test package once before all tests are run.""" | 72 """Installs the test package once before all tests are run.""" |
72 pass | 73 pass |
73 | 74 |
74 def PushDataDeps(self): | 75 def PushDataDeps(self): |
75 """Push all data deps to device once before all tests are run.""" | 76 """Push all data deps to device once before all tests are run.""" |
76 pass | 77 pass |
77 | 78 |
78 def SetUp(self): | 79 def SetUp(self): |
79 """Run once before all tests are run.""" | 80 """Run once before all tests are run.""" |
80 self.InstallTestPackage() | 81 self.InstallTestPackage() |
81 push_size_before = self.adb.GetPushSizeInfo() | 82 push_size_before = self.device.old_interface.GetPushSizeInfo() |
82 if self._push_deps: | 83 if self._push_deps: |
83 logging.warning('Pushing data files to device.') | 84 logging.warning('Pushing data files to device.') |
84 self.PushDataDeps() | 85 self.PushDataDeps() |
85 push_size_after = self.adb.GetPushSizeInfo() | 86 push_size_after = self.device.old_interface.GetPushSizeInfo() |
86 logging.warning( | 87 logging.warning( |
87 'Total data: %0.3fMB' % | 88 'Total data: %0.3fMB' % |
88 ((push_size_after[0] - push_size_before[0]) / float(2 ** 20))) | 89 ((push_size_after[0] - push_size_before[0]) / float(2 ** 20))) |
89 logging.warning( | 90 logging.warning( |
90 'Total data transferred: %0.3fMB' % | 91 'Total data transferred: %0.3fMB' % |
91 ((push_size_after[1] - push_size_before[1]) / float(2 ** 20))) | 92 ((push_size_after[1] - push_size_before[1]) / float(2 ** 20))) |
92 else: | 93 else: |
93 logging.warning('Skipping pushing data to device.') | 94 logging.warning('Skipping pushing data to device.') |
94 | 95 |
95 def TearDown(self): | 96 def TearDown(self): |
96 """Run once after all tests are run.""" | 97 """Run once after all tests are run.""" |
97 self.ShutdownHelperToolsForTestSuite() | 98 self.ShutdownHelperToolsForTestSuite() |
98 if self._cleanup_test_files: | 99 if self._cleanup_test_files: |
99 self.adb.RemovePushedFiles() | 100 self.device.old_interface.RemovePushedFiles() |
100 | 101 |
101 def LaunchTestHttpServer(self, document_root, port=None, | 102 def LaunchTestHttpServer(self, document_root, port=None, |
102 extra_config_contents=None): | 103 extra_config_contents=None): |
103 """Launches an HTTP server to serve HTTP tests. | 104 """Launches an HTTP server to serve HTTP tests. |
104 | 105 |
105 Args: | 106 Args: |
106 document_root: Document root of the HTTP server. | 107 document_root: Document root of the HTTP server. |
107 port: port on which we want to the http server bind. | 108 port: port on which we want to the http server bind. |
108 extra_config_contents: Extra config contents for the HTTP server. | 109 extra_config_contents: Extra config contents for the HTTP server. |
109 """ | 110 """ |
110 self._http_server = lighttpd_server.LighttpdServer( | 111 self._http_server = lighttpd_server.LighttpdServer( |
111 document_root, port=port, extra_config_contents=extra_config_contents) | 112 document_root, port=port, extra_config_contents=extra_config_contents) |
112 if self._http_server.StartupHttpServer(): | 113 if self._http_server.StartupHttpServer(): |
113 logging.info('http server started: http://localhost:%s', | 114 logging.info('http server started: http://localhost:%s', |
114 self._http_server.port) | 115 self._http_server.port) |
115 else: | 116 else: |
116 logging.critical('Failed to start http server') | 117 logging.critical('Failed to start http server') |
117 self._ForwardPortsForHttpServer() | 118 self._ForwardPortsForHttpServer() |
118 return (self._forwarder_device_port, self._http_server.port) | 119 return (self._forwarder_device_port, self._http_server.port) |
119 | 120 |
120 def _ForwardPorts(self, port_pairs): | 121 def _ForwardPorts(self, port_pairs): |
121 """Forwards a port.""" | 122 """Forwards a port.""" |
122 Forwarder.Map(port_pairs, self.adb, self.tool) | 123 Forwarder.Map(port_pairs, self.device, self.tool) |
123 | 124 |
124 def _UnmapPorts(self, port_pairs): | 125 def _UnmapPorts(self, port_pairs): |
125 """Unmap previously forwarded ports.""" | 126 """Unmap previously forwarded ports.""" |
126 for (device_port, _) in port_pairs: | 127 for (device_port, _) in port_pairs: |
127 Forwarder.UnmapDevicePort(device_port, self.adb) | 128 Forwarder.UnmapDevicePort(device_port, self.device) |
128 | 129 |
129 # Deprecated: Use ForwardPorts instead. | 130 # Deprecated: Use ForwardPorts instead. |
130 def StartForwarder(self, port_pairs): | 131 def StartForwarder(self, port_pairs): |
131 """Starts TCP traffic forwarding for the given |port_pairs|. | 132 """Starts TCP traffic forwarding for the given |port_pairs|. |
132 | 133 |
133 Args: | 134 Args: |
134 host_port_pairs: A list of (device_port, local_port) tuples to forward. | 135 host_port_pairs: A list of (device_port, local_port) tuples to forward. |
135 """ | 136 """ |
136 self._ForwardPorts(port_pairs) | 137 self._ForwardPorts(port_pairs) |
137 | 138 |
138 def _ForwardPortsForHttpServer(self): | 139 def _ForwardPortsForHttpServer(self): |
139 """Starts a forwarder for the HTTP server. | 140 """Starts a forwarder for the HTTP server. |
140 | 141 |
141 The forwarder forwards HTTP requests and responses between host and device. | 142 The forwarder forwards HTTP requests and responses between host and device. |
142 """ | 143 """ |
143 self._ForwardPorts([(self._forwarder_device_port, self._http_server.port)]) | 144 self._ForwardPorts([(self._forwarder_device_port, self._http_server.port)]) |
144 | 145 |
145 def _RestartHttpServerForwarderIfNecessary(self): | 146 def _RestartHttpServerForwarderIfNecessary(self): |
146 """Restarts the forwarder if it's not open.""" | 147 """Restarts the forwarder if it's not open.""" |
147 # Checks to see if the http server port is being used. If not forwards the | 148 # Checks to see if the http server port is being used. If not forwards the |
148 # request. | 149 # request. |
149 # TODO(dtrainor): This is not always reliable because sometimes the port | 150 # TODO(dtrainor): This is not always reliable because sometimes the port |
150 # will be left open even after the forwarder has been killed. | 151 # will be left open even after the forwarder has been killed. |
151 if not ports.IsDevicePortUsed(self.adb, self._forwarder_device_port): | 152 if not ports.IsDevicePortUsed(self.device, self._forwarder_device_port): |
152 self._ForwardPortsForHttpServer() | 153 self._ForwardPortsForHttpServer() |
153 | 154 |
154 def ShutdownHelperToolsForTestSuite(self): | 155 def ShutdownHelperToolsForTestSuite(self): |
155 """Shuts down the server and the forwarder.""" | 156 """Shuts down the server and the forwarder.""" |
156 if self._http_server: | 157 if self._http_server: |
157 self._UnmapPorts([(self._forwarder_device_port, self._http_server.port)]) | 158 self._UnmapPorts([(self._forwarder_device_port, self._http_server.port)]) |
158 self._http_server.ShutdownHttpServer() | 159 self._http_server.ShutdownHttpServer() |
159 if self._spawning_server: | 160 if self._spawning_server: |
160 self._spawning_server.Stop() | 161 self._spawning_server.Stop() |
161 | 162 |
(...skipping 12 matching lines...) Expand all Loading... |
174 error_msgs = [] | 175 error_msgs = [] |
175 # TODO(pliard): deflake this function. The for loop should be removed as | 176 # TODO(pliard): deflake this function. The for loop should be removed as |
176 # well as IsHttpServerConnectable(). spawning_server.Start() should also | 177 # well as IsHttpServerConnectable(). spawning_server.Start() should also |
177 # block until the server is ready. | 178 # block until the server is ready. |
178 # Try 3 times to launch test spawner server. | 179 # Try 3 times to launch test spawner server. |
179 for _ in xrange(0, 3): | 180 for _ in xrange(0, 3): |
180 self.test_server_spawner_port = ports.AllocateTestServerPort() | 181 self.test_server_spawner_port = ports.AllocateTestServerPort() |
181 self._ForwardPorts( | 182 self._ForwardPorts( |
182 [(self.test_server_spawner_port, self.test_server_spawner_port)]) | 183 [(self.test_server_spawner_port, self.test_server_spawner_port)]) |
183 self._spawning_server = SpawningServer(self.test_server_spawner_port, | 184 self._spawning_server = SpawningServer(self.test_server_spawner_port, |
184 self.adb, | 185 self.device, |
185 self.tool) | 186 self.tool) |
186 self._spawning_server.Start() | 187 self._spawning_server.Start() |
187 server_ready, error_msg = ports.IsHttpServerConnectable( | 188 server_ready, error_msg = ports.IsHttpServerConnectable( |
188 '127.0.0.1', self.test_server_spawner_port, path='/ping', | 189 '127.0.0.1', self.test_server_spawner_port, path='/ping', |
189 expected_read='ready') | 190 expected_read='ready') |
190 if server_ready: | 191 if server_ready: |
191 break | 192 break |
192 else: | 193 else: |
193 error_msgs.append(error_msg) | 194 error_msgs.append(error_msg) |
194 self._spawning_server.Stop() | 195 self._spawning_server.Stop() |
195 # Wait for 2 seconds then restart. | 196 # Wait for 2 seconds then restart. |
196 time.sleep(2) | 197 time.sleep(2) |
197 if not server_ready: | 198 if not server_ready: |
198 logging.error(';'.join(error_msgs)) | 199 logging.error(';'.join(error_msgs)) |
199 raise Exception('Can not start the test spawner server.') | 200 raise Exception('Can not start the test spawner server.') |
200 self._PushTestServerPortInfoToDevice() | 201 self._PushTestServerPortInfoToDevice() |
OLD | NEW |