OLD | NEW |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2013 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 """Dispatches GTests.""" | 5 """Runs GTests.""" |
6 | 6 |
7 import copy | 7 import copy |
8 import fnmatch | 8 import fnmatch |
9 import glob | 9 import glob |
10 import logging | 10 import logging |
11 import os | 11 import os |
12 import shutil | 12 import shutil |
13 | 13 |
14 from pylib import android_commands | 14 from pylib import android_commands |
15 from pylib import cmd_helper | 15 from pylib import cmd_helper |
16 from pylib import constants | 16 from pylib import constants |
| 17 from pylib import dispatch |
17 from pylib import ports | 18 from pylib import ports |
18 from pylib.base import base_test_result | 19 from pylib.base import base_test_result |
19 from pylib.base import shard | 20 from pylib.base import shard |
20 from pylib.utils import emulator | 21 from pylib.utils import emulator |
21 from pylib.utils import report_results | 22 from pylib.utils import report_results |
22 from pylib.utils import xvfb | |
23 | 23 |
24 import gtest_config | 24 import gtest_config |
25 import test_runner | 25 import test_runner |
26 | 26 |
27 | 27 |
28 # TODO(frankf): Add more test targets here after making sure we don't | 28 # TODO(frankf): Add more test targets here after making sure we don't |
29 # blow up the dependency size (and the world). | 29 # blow up the dependency size (and the world). |
30 _ISOLATE_FILE_PATHS = { | 30 _ISOLATE_FILE_PATHS = { |
31 'base_unittests': 'base/base_unittests.isolate', | 31 'base_unittests': 'base/base_unittests.isolate', |
32 'unit_tests': 'chrome/unit_tests.isolate', | 32 'unit_tests': 'chrome/unit_tests.isolate', |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 all_tests) | 200 all_tests) |
201 | 201 |
202 | 202 |
203 def GetAllEnabledTests(runner_factory, devices): | 203 def GetAllEnabledTests(runner_factory, devices): |
204 """Get all enabled tests. | 204 """Get all enabled tests. |
205 | 205 |
206 Obtains a list of enabled tests from the test package on the device, | 206 Obtains a list of enabled tests from the test package on the device, |
207 then filters it again using the disabled list on the host. | 207 then filters it again using the disabled list on the host. |
208 | 208 |
209 Args: | 209 Args: |
210 runner_factory: callable that takes a devices and returns a TestRunner. | 210 runner_factory: callable that takes device and shard_index and returns |
211 devices: list of devices. | 211 a TestRunner. |
212 | 212 |
213 Returns: | 213 Returns: |
214 List of all enabled tests. | 214 List of all enabled tests. |
215 | 215 |
216 Raises: | 216 Raises: |
217 Exception: If no devices available. | 217 Exception: If no devices available. |
218 """ | 218 """ |
219 for device in devices: | 219 for device in devices: |
220 try: | 220 try: |
221 logging.info('Obtaining tests from %s', device) | 221 logging.info('Obtaining tests from %s', device) |
(...skipping 16 matching lines...) Expand all Loading... |
238 options: options for running the tests. | 238 options: options for running the tests. |
239 suite_name: name of the test suite being run. | 239 suite_name: name of the test suite being run. |
240 | 240 |
241 Returns: | 241 Returns: |
242 A tuple of (base_test_result.TestRunResult object, exit code). | 242 A tuple of (base_test_result.TestRunResult object, exit code). |
243 | 243 |
244 Raises: | 244 Raises: |
245 Exception: For various reasons including device failure or failing to reset | 245 Exception: For various reasons including device failure or failing to reset |
246 the test server port. | 246 the test server port. |
247 """ | 247 """ |
248 attached_devices = [] | |
249 buildbot_emulators = [] | |
250 | |
251 if options.use_emulator: | |
252 buildbot_emulators = emulator.LaunchEmulators(options.emulator_count, | |
253 options.abi, | |
254 wait_for_boot=True) | |
255 attached_devices = [e.device for e in buildbot_emulators] | |
256 elif options.test_device: | |
257 attached_devices = [options.test_device] | |
258 else: | |
259 attached_devices = android_commands.GetAttachedDevices() | |
260 | |
261 if not attached_devices: | |
262 raise Exception('A device must be attached and online.') | |
263 | 248 |
264 # Reset the test port allocation. It's important to do it before starting | 249 # Reset the test port allocation. It's important to do it before starting |
265 # to dispatch any tests. | 250 # to dispatch any tests. |
266 if not ports.ResetTestServerPortAllocation(): | 251 if not ports.ResetTestServerPortAllocation(): |
267 raise Exception('Failed to reset test server port.') | 252 raise Exception('Failed to reset test server port.') |
268 | 253 |
269 deps_dir = _GenerateDepsDirUsingIsolate(suite_name, options.build_type) | 254 deps_dir = _GenerateDepsDirUsingIsolate(suite_name, options.build_type) |
270 | 255 |
271 # Constructs a new TestRunner with the current options. | 256 # Constructs a new TestRunner with the current options. |
272 def RunnerFactory(device, shard_index): | 257 def TestRunnerFactory(device, shard_index): |
273 return test_runner.TestRunner( | 258 return test_runner.TestRunner( |
274 device, | 259 device, |
275 options.test_suite, | 260 options.test_suite, |
276 options.test_arguments, | 261 options.test_arguments, |
277 options.timeout, | 262 options.timeout, |
278 options.cleanup_test_files, | 263 options.cleanup_test_files, |
279 options.tool, | 264 options.tool, |
280 options.build_type, | 265 options.build_type, |
281 options.webkit, | 266 options.webkit, |
282 options.push_deps, | 267 options.push_deps, |
283 constants.GTEST_TEST_PACKAGE_NAME, | 268 constants.GTEST_TEST_PACKAGE_NAME, |
284 constants.GTEST_TEST_ACTIVITY_NAME, | 269 constants.GTEST_TEST_ACTIVITY_NAME, |
285 constants.GTEST_COMMAND_LINE_FILE, | 270 constants.GTEST_COMMAND_LINE_FILE, |
286 deps_dir=deps_dir) | 271 deps_dir=deps_dir) |
287 | 272 |
| 273 # TODO(gkanwar): This breaks the abstraction of having dispatch.Dispatch deal |
| 274 # entirely with the devices. Can we do this another way? |
| 275 attached_devices = android_commands.GetAttachedDevices() |
288 # Get tests and split them up based on the number of devices. | 276 # Get tests and split them up based on the number of devices. |
289 if options.test_filter: | 277 if options.test_filter: |
290 all_tests = [t for t in options.test_filter.split(':') if t] | 278 all_tests = [t for t in options.test_filter.split(':') if t] |
291 else: | 279 else: |
292 all_tests = GetAllEnabledTests(RunnerFactory, attached_devices) | 280 all_tests = GetAllEnabledTests(TestRunnerFactory, attached_devices) |
293 num_devices = len(attached_devices) | 281 num_devices = len(attached_devices) |
294 tests = [':'.join(all_tests[i::num_devices]) for i in xrange(num_devices)] | 282 tests = [':'.join(all_tests[i::num_devices]) for i in xrange(num_devices)] |
295 tests = [t for t in tests if t] | 283 tests = [t for t in tests if t] |
296 | 284 |
297 # Run tests. | 285 # Run tests. |
298 test_results, exit_code = shard.ShardAndRunTests( | 286 test_results, exit_code = dispatch.Dispatch(options, tests, TestRunnerFactory, |
299 RunnerFactory, attached_devices, tests, options.build_type, | 287 distribution='shard') |
300 test_timeout=None, num_retries=options.num_retries) | |
301 | 288 |
302 report_results.LogFull( | 289 report_results.LogFull( |
303 results=test_results, | 290 results=test_results, |
304 test_type='Unit test', | 291 test_type='Unit test', |
305 test_package=suite_name, | 292 test_package=suite_name, |
306 build_type=options.build_type, | 293 build_type=options.build_type, |
307 flakiness_server=options.flakiness_dashboard_server) | 294 flakiness_server=options.flakiness_dashboard_server) |
308 | 295 |
309 for buildbot_emulator in buildbot_emulators: | |
310 buildbot_emulator.Shutdown() | |
311 | 296 |
312 return (test_results, exit_code) | 297 return (test_results, exit_code) |
313 | 298 |
314 | 299 |
315 def _ListTestSuites(): | 300 def _ListTestSuites(): |
316 """Display a list of available test suites.""" | 301 """Display a list of available test suites.""" |
317 print 'Available test suites are:' | 302 print 'Available test suites are:' |
318 for test_suite in gtest_config.STABLE_TEST_SUITES: | 303 for test_suite in gtest_config.STABLE_TEST_SUITES: |
319 print test_suite | 304 print test_suite |
320 | 305 |
321 | 306 |
322 def Dispatch(options): | 307 def RunGTests(options): |
323 """Dispatches the tests, sharding if possible. | 308 """Runs the tests, sharding if possible. |
324 | 309 |
325 If options.use_emulator is True, all tests will be run in new emulator | 310 If options.use_emulator is True, all tests will be run in new emulator |
326 instance. | 311 instance. |
327 | 312 |
328 Args: | 313 Args: |
329 options: options for running the tests. | 314 options: options for running the tests. |
330 | 315 |
331 Returns: | 316 Returns: |
332 base_test_result.TestRunResults object with the results of running the tests | 317 base_test_result.TestRunResults object with the results of running the tests |
333 """ | 318 """ |
334 results = base_test_result.TestRunResults() | 319 results = base_test_result.TestRunResults() |
335 | 320 |
336 if options.test_suite == 'help': | 321 if options.test_suite == 'help': |
337 _ListTestSuites() | 322 _ListTestSuites() |
338 return (results, 0) | 323 return (results, 0) |
339 | 324 |
340 if options.use_xvfb: | |
341 framebuffer = xvfb.Xvfb() | |
342 framebuffer.Start() | |
343 | |
344 all_test_suites = _FullyQualifiedTestSuites(options.exe, options.test_suite, | 325 all_test_suites = _FullyQualifiedTestSuites(options.exe, options.test_suite, |
345 options.build_type) | 326 options.build_type) |
346 exit_code = 0 | 327 exit_code = 0 |
347 for suite_name, suite_path in all_test_suites: | 328 for suite_name, suite_path in all_test_suites: |
348 # Give each test suite its own copy of options. | 329 # Give each test suite its own copy of options. |
349 test_options = copy.deepcopy(options) | 330 test_options = copy.deepcopy(options) |
350 test_options.test_suite = suite_path | 331 test_options.test_suite = suite_path |
351 test_results, test_exit_code = _RunATestSuite(test_options, suite_name) | 332 test_results, test_exit_code = _RunATestSuite(test_options, suite_name) |
352 results.AddTestRunResults(test_results) | 333 results.AddTestRunResults(test_results) |
353 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE: | 334 if test_exit_code and exit_code != constants.ERROR_EXIT_CODE: |
354 exit_code = test_exit_code | 335 exit_code = test_exit_code |
355 | 336 |
356 if options.use_xvfb: | |
357 framebuffer.Stop() | |
358 | |
359 return (results, exit_code) | 337 return (results, exit_code) |
OLD | NEW |