1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 """Generates test runner factory and tests for GTests."""
6 # pylint: disable=W0212
12 from devil
.android
import device_utils
13 from pylib
import constants
14 from pylib
.base
import base_setup
15 from pylib
.base
import base_test_result
16 from pylib
.base
import test_dispatcher
17 from pylib
.gtest
import gtest_test_instance
18 from pylib
.gtest
import test_package_apk
19 from pylib
.gtest
import test_package_exe
20 from pylib
.gtest
import test_runner
23 os
.path
.join(constants
.DIR_SOURCE_ROOT
, 'build', 'util', 'lib',
25 import unittest_util
# pylint: disable=F0401
28 ISOLATE_FILE_PATHS
= gtest_test_instance
._DEFAULT
_ISOLATE
_FILE
_PATHS
31 # Used for filtering large data deps at a finer grain than what's allowed in
32 # isolate files since pushing deps to devices is expensive.
33 # Wildcards are allowed.
34 DEPS_EXCLUSION_LIST
= [
35 'chrome/test/data/extensions/api_test',
36 'chrome/test/data/extensions/secure_shell',
37 'chrome/test/data/firefox*',
38 'chrome/test/data/gpu',
39 'chrome/test/data/image_decoding',
40 'chrome/test/data/import',
41 'chrome/test/data/page_cycler',
42 'chrome/test/data/perf',
43 'chrome/test/data/pyauto_private',
44 'chrome/test/data/safari_import',
45 'chrome/test/data/scroll',
46 'chrome/test/data/third_party',
47 'third_party/hunspell_dictionaries/*.dic',
49 'webkit/data/bmp_decoder',
50 'webkit/data/ico_decoder',
54 def _GetDisabledTestsFilterFromFile(suite_name
):
55 """Returns a gtest filter based on the *_disabled file.
58 suite_name: Name of the test suite (e.g. base_unittests).
61 A gtest filter which excludes disabled tests.
62 Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc'
64 filter_file_path
= os
.path
.join(
65 os
.path
.abspath(os
.path
.dirname(__file__
)),
66 'filter', '%s_disabled' % suite_name
)
68 if not filter_file_path
or not os
.path
.exists(filter_file_path
):
69 logging
.info('No filter file found at %s', filter_file_path
)
72 filters
= [x
for x
in [x
.strip() for x
in file(filter_file_path
).readlines()]
74 disabled_filter
= '*-%s' % ':'.join(filters
)
75 logging
.info('Applying filter "%s" obtained from %s',
76 disabled_filter
, filter_file_path
)
77 return disabled_filter
80 def _GetTests(test_options
, test_package
, devices
):
81 """Get a list of tests.
84 test_options: A GTestOptions object.
85 test_package: A TestPackageApk object.
86 devices: A list of attached devices.
89 A list of all the tests in the test suite.
91 class TestListResult(base_test_result
.BaseTestResult
):
93 super(TestListResult
, self
).__init
__(
94 'gtest_list_tests', base_test_result
.ResultType
.PASS
)
97 def TestListerRunnerFactory(device
, _shard_index
):
98 class TestListerRunner(test_runner
.TestRunner
):
99 def RunTest(self
, _test
):
100 result
= TestListResult()
101 self
.test_package
.Install(self
.device
)
102 result
.test_list
= self
.test_package
.GetAllTests(self
.device
)
103 results
= base_test_result
.TestRunResults()
104 results
.AddResult(result
)
106 return TestListerRunner(test_options
, device
, test_package
)
108 results
, _
= test_dispatcher
.RunTests(
109 ['gtest_list_tests'], TestListerRunnerFactory
, devices
)
111 for r
in results
.GetAll():
112 tests
.extend(r
.test_list
)
116 def _FilterTestsUsingPrefixes(all_tests
, pre
=False, manual
=False):
117 """Removes tests with disabled prefixes.
120 all_tests: List of tests to filter.
121 pre: If True, include tests with PRE_ prefix.
122 manual: If True, include tests with MANUAL_ prefix.
125 List of tests remaining.
128 filter_prefixes
= ['DISABLED_', 'FLAKY_', 'FAILS_']
131 filter_prefixes
.append('PRE_')
134 filter_prefixes
.append('MANUAL_')
137 test_case
, test
= t
.split('.', 1)
138 if not any([test_case
.startswith(prefix
) or test
.startswith(prefix
) for
139 prefix
in filter_prefixes
]):
140 filtered_tests
.append(t
)
141 return filtered_tests
144 def _FilterDisabledTests(tests
, suite_name
, has_gtest_filter
):
145 """Removes disabled tests from |tests|.
147 Applies the following filters in order:
148 1. Remove tests with disabled prefixes.
149 2. Remove tests specified in the *_disabled files in the 'filter' dir
152 tests: List of tests.
153 suite_name: Name of the test suite (e.g. base_unittests).
154 has_gtest_filter: Whether a gtest_filter is provided.
157 List of tests remaining.
159 tests
= _FilterTestsUsingPrefixes(
160 tests
, has_gtest_filter
, has_gtest_filter
)
161 tests
= unittest_util
.FilterTestNames(
162 tests
, _GetDisabledTestsFilterFromFile(suite_name
))
167 def Setup(test_options
, devices
):
168 """Create the test runner factory and tests.
171 test_options: A GTestOptions object.
172 devices: A list of attached devices.
175 A tuple of (TestRunnerFactory, tests).
177 test_package
= test_package_apk
.TestPackageApk(test_options
.suite_name
)
178 if not os
.path
.exists(test_package
.suite_path
):
179 exe_test_package
= test_package_exe
.TestPackageExecutable(
180 test_options
.suite_name
)
181 if not os
.path
.exists(exe_test_package
.suite_path
):
183 'Did not find %s target. Ensure it has been built.\n'
184 '(not found at %s or %s)'
185 % (test_options
.suite_name
,
186 test_package
.suite_path
,
187 exe_test_package
.suite_path
))
188 test_package
= exe_test_package
189 logging
.warning('Found target %s', test_package
.suite_path
)
191 i
= base_setup
.GenerateDepsDirUsingIsolate(test_options
.suite_name
,
192 test_options
.isolate_file_path
,
195 def push_data_deps_to_device_dir(device
):
196 device_dir
= (constants
.TEST_EXECUTABLE_DIR
197 if test_package
.suite_name
== 'breakpad_unittests'
198 else device
.GetExternalStoragePath())
199 base_setup
.PushDataDeps(device
, device_dir
, test_options
)
200 device_utils
.DeviceUtils
.parallel(devices
).pMap(push_data_deps_to_device_dir
)
204 tests
= _GetTests(test_options
, test_package
, devices
)
206 # Constructs a new TestRunner with the current options.
207 def TestRunnerFactory(device
, _shard_index
):
208 return test_runner
.TestRunner(
213 if test_options
.run_disabled
:
214 test_options
= test_options
._replace
(
215 test_arguments
=('%s --gtest_also_run_disabled_tests' %
216 test_options
.test_arguments
))
218 tests
= _FilterDisabledTests(tests
, test_options
.suite_name
,
219 bool(test_options
.gtest_filter
))
220 if test_options
.gtest_filter
:
221 tests
= unittest_util
.FilterTestNames(tests
, test_options
.gtest_filter
)
223 # Coalesce unit tests into a single test per device
224 if test_options
.suite_name
not in gtest_test_instance
.BROWSER_TEST_SUITES
:
225 num_devices
= len(devices
)
226 tests
= [':'.join(tests
[i
::num_devices
]) for i
in xrange(num_devices
)]
227 tests
= [t
for t
in tests
if t
]
229 return (TestRunnerFactory
, tests
)