Index: build/android/pylib/local/device/local_device_gtest_run.py |
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py |
index 85af2bc2c3365e59388f37a85f4980f2fbe208bf..81d85fda484730d9fa8e8d100dc1e847e5142ae9 100644 |
--- a/build/android/pylib/local/device/local_device_gtest_run.py |
+++ b/build/android/pylib/local/device/local_device_gtest_run.py |
@@ -52,6 +52,32 @@ def PullAppFilesImpl(device, package, files, directory): |
break |
device.PullFile(device_file, host_file) |
+ |
+def _ExtractTestsFromFilter(gtest_filter): |
+ """Returns the list of tests specified by the given filter. |
+ |
+ Returns: |
+ None if the device should be queried for the test list instead. |
+ """ |
+ # Empty means all tests, - means exclude filter. |
+ if not gtest_filter or '-' in gtest_filter: |
+ return None |
+ |
+ patterns = gtest_filter.split(':') |
+ # For a single pattern, allow it even if it has a wildcard so long as the |
+ # wildcard comes at the end and there is at least one . to prove the scope is |
+ # not too large. |
+ # This heuristic is not necessarily faster, but normally is. |
+ if len(patterns) == 1 and patterns[0].endswith('*'): |
+ no_suffix = patterns[0].rstrip('*') |
+ if '*' not in no_suffix and '.' in no_suffix: |
+ return patterns |
+ |
+ if '*' in gtest_filter: |
+ return None |
+ return patterns |
+ |
+ |
class _ApkDelegate(object): |
def __init__(self, test_instance): |
self._activity = test_instance.activity |
@@ -221,6 +247,16 @@ class LocalDeviceGtestRun(local_device_test_run.LocalDeviceTestRun): |
#override |
def _GetTests(self): |
+ # When the exact list of tests to run is given via command-line (e.g. when |
+ # locally iterating on a specific test), skip querying the device (which |
+ # takes ~3 seconds). |
+ tests = _ExtractTestsFromFilter(self._test_instance.gtest_filter) |
+ if tests: |
+ return tests |
+ |
+ # Even when there's only one device, it still makes sense to retrieve the |
+ # test list so that tests can be split up and run in batches rather than all |
+ # at once (since test output is not streamed). |
@local_device_test_run.handle_shard_failures_with( |
on_failure=self._env.BlacklistDevice) |
def list_tests(dev): |
@@ -230,9 +266,11 @@ class LocalDeviceGtestRun(local_device_test_run.LocalDeviceTestRun): |
tests = self._test_instance.FilterTests(tests) |
return tests |
+ # Query all devices in case one fails. |
test_lists = self._env.parallel_devices.pMap(list_tests).pGet(None) |
- tests = list(sorted(set().union(*[set(tl) for tl in test_lists if tl]))) |
- return tests |
+ # TODO(agrieve): Make this fail rather than return an empty list when |
+ # all devices fail. |
+ return list(sorted(set().union(*[set(tl) for tl in test_lists if tl]))) |
#override |
def _RunTest(self, device, test): |