Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(681)

Unified Diff: build/android/run_tests.py

Issue 9494007: Upstream test sharder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: N emulators launched asynchronously Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/android/emulator.py ('k') | build/android/single_test_runner.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/run_tests.py
diff --git a/build/android/run_tests.py b/build/android/run_tests.py
index f945beeeb3c7063945b793cf501848c561422ed1..78019bd3ded500261ea5f1232e54657fc83cc0df 100755
--- a/build/android/run_tests.py
+++ b/build/android/run_tests.py
@@ -47,7 +47,9 @@ loaded. We don't care about the rare testcases which succeeded on emuatlor, but
failed on device.
"""
+import fnmatch
import logging
+import multiprocessing
import os
import re
import subprocess
@@ -55,6 +57,7 @@ import sys
import time
import android_commands
+from base_test_sharder import BaseTestSharder
import cmd_helper
import debug_info
import emulator
@@ -140,7 +143,7 @@ class Xvfb(object):
def RunTests(device, test_suite, gtest_filter, test_arguments, rebaseline,
timeout, performance_test, cleanup_test_files, tool,
- log_dump_name, fast_and_loose=False, annotate=False):
+ log_dump_name, annotate=False):
"""Runs the tests.
Args:
@@ -154,8 +157,6 @@ def RunTests(device, test_suite, gtest_filter, test_arguments, rebaseline,
cleanup_test_files: Whether or not to cleanup test files on device.
tool: Name of the Valgrind tool.
log_dump_name: Name of log dump file.
- fast_and_loose: should we go extra-fast but sacrifice stability
- and/or correctness? Intended for quick cycle testing; not for bots!
annotate: should we print buildbot-style annotations?
Returns:
@@ -183,9 +184,8 @@ def RunTests(device, test_suite, gtest_filter, test_arguments, rebaseline,
print '@@@BUILD_STEP Test suite %s@@@' % os.path.basename(t)
test = SingleTestRunner(device, t, gtest_filter, test_arguments,
timeout, rebaseline, performance_test,
- cleanup_test_files, tool, not not log_dump_name,
- fast_and_loose=fast_and_loose)
- test.RunTests()
+ cleanup_test_files, tool, 0, not not log_dump_name)
+ test.Run()
results += [test.test_results]
# Collect debug info.
@@ -211,6 +211,61 @@ def RunTests(device, test_suite, gtest_filter, test_arguments, rebaseline,
return TestResults.FromTestResults(results)
+class TestSharder(BaseTestSharder):
+ """Responsible for sharding the tests on the connected devices."""
+
+ def __init__(self, attached_devices, test_suite, gtest_filter,
+ test_arguments, timeout, rebaseline, performance_test,
+ cleanup_test_files, tool):
+ BaseTestSharder.__init__(self, attached_devices)
+ self.test_suite = test_suite
+ self.test_suite_basename = os.path.basename(test_suite)
+ self.gtest_filter = gtest_filter
+ self.test_arguments = test_arguments
+ self.timeout = timeout
+ self.rebaseline = rebaseline
+ self.performance_test = performance_test
+ self.cleanup_test_files = cleanup_test_files
+ self.tool = tool
+ test = SingleTestRunner(self.attached_devices[0], test_suite, gtest_filter,
+ test_arguments, timeout, rebaseline,
+ performance_test, cleanup_test_files, tool, 0)
+ all_tests = test.test_package.GetAllTests()
+ if not rebaseline:
+ disabled_list = test.GetDisabledTests()
+ # Only includes tests that do not have any match in the disabled list.
+ all_tests = filter(lambda t:
+ not any([fnmatch.fnmatch(t, disabled_pattern)
+ for disabled_pattern in disabled_list]),
+ all_tests)
+ self.tests = all_tests
+
+ def CreateShardedTestRunner(self, device, index):
+ """Creates a suite-specific test runner.
+
+ Args:
+ device: Device serial where this shard will run.
+ index: Index of this device in the pool.
+
+ Returns:
+ A SingleTestRunner object.
+ """
+ shard_size = len(self.tests) / len(self.attached_devices)
+ shard_test_list = self.tests[index * shard_size : (index + 1) * shard_size]
+ test_filter = ':'.join(shard_test_list)
+ return SingleTestRunner(device, self.test_suite,
+ test_filter, self.test_arguments, self.timeout,
+ self.rebaseline, self.performance_test,
+ self.cleanup_test_files, self.tool, index)
+
+ def OnTestsCompleted(self, test_runners, test_results):
+ """Notifies that we completed the tests."""
+ test_results.LogFull()
+ if test_results.failed and self.rebaseline:
+ test_runners[0].UpdateFilter(test_results.failed)
+
+
+
def _RunATestSuite(options):
"""Run a single test suite.
@@ -225,14 +280,19 @@ def _RunATestSuite(options):
0 if successful, number of failing tests otherwise.
"""
attached_devices = []
- buildbot_emulator = None
+ buildbot_emulators = []
if options.use_emulator:
- t = TimeProfile('Emulator launch')
- buildbot_emulator = emulator.Emulator(options.fast_and_loose)
- buildbot_emulator.Launch()
- t.Stop()
- attached_devices.append(buildbot_emulator.device)
+ for n in range(options.use_emulator):
+ t = TimeProfile('Emulator launch %d' % n)
+ buildbot_emulator = emulator.Emulator(options.fast_and_loose)
+ buildbot_emulator.Launch(kill_all_emulators=n == 0)
+ t.Stop()
+ buildbot_emulators.append(buildbot_emulator)
+ attached_devices.append(buildbot_emulator.device)
+ # Wait for all emulators to become available.
+ map(lambda buildbot_emulator:buildbot_emulator.ConfirmLaunch(),
+ buildbot_emulators)
else:
attached_devices = android_commands.GetAttachedDevices()
@@ -240,16 +300,24 @@ def _RunATestSuite(options):
logging.critical('A device must be attached and online.')
return 1
- test_results = RunTests(attached_devices[0], options.test_suite,
+ if (len(attached_devices) > 1 and options.test_suite and
+ not options.gtest_filter and not options.performance_test):
+ sharder = TestSharder(attached_devices, options.test_suite,
options.gtest_filter, options.test_arguments,
- options.rebaseline, options.timeout,
+ options.timeout, options.rebaseline,
options.performance_test,
- options.cleanup_test_files, options.tool,
- options.log_dump,
- fast_and_loose=options.fast_and_loose,
- annotate=options.annotate)
-
- if buildbot_emulator:
+ options.cleanup_test_files, options.tool)
+ test_results = sharder.RunShardedTests()
+ else:
+ test_results = RunTests(attached_devices[0], options.test_suite,
+ options.gtest_filter, options.test_arguments,
+ options.rebaseline, options.timeout,
+ options.performance_test,
+ options.cleanup_test_files, options.tool,
+ options.log_dump,
+ annotate=options.annotate)
+
+ for buildbot_emulator in buildbot_emulators:
buildbot_emulator.Shutdown()
# Another chance if we timed out? At this point It is safe(r) to
@@ -330,8 +398,8 @@ def main(argv):
'in where the test_suite exists.')
option_parser.add_option('-e', '--emulator', dest='use_emulator',
help='Run tests in a new instance of emulator',
- action='store_true',
- default=False)
+ type='int',
+ default=0)
option_parser.add_option('-x', '--xvfb', dest='use_xvfb',
action='store_true', default=False,
help='Use Xvfb around tests (ignored if not Linux)')
« no previous file with comments | « build/android/emulator.py ('k') | build/android/single_test_runner.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698