Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / build / android / pylib / gtest / setup.py
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.
4
5 """Generates test runner factory and tests for GTests."""
6 # pylint: disable=W0212
7
8 import logging
9 import os
10 import sys
11
12 from pylib import constants
13 from pylib import valgrind_tools
14
15 from pylib.base import base_test_result
16 from pylib.base import test_dispatcher
17 from pylib.device import device_utils
18 from pylib.gtest import test_package_apk
19 from pylib.gtest import test_package_exe
20 from pylib.gtest import test_runner
21 from pylib.utils import isolator
22
23 sys.path.insert(0,
24                 os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib',
25                              'common'))
26 import unittest_util # pylint: disable=F0401
27
28
29 _ISOLATE_FILE_PATHS = {
30     'base_unittests': 'base/base_unittests.isolate',
31     'blink_heap_unittests':
32       'third_party/WebKit/Source/platform/heap/BlinkHeapUnitTests.isolate',
33     'breakpad_unittests': 'breakpad/breakpad_unittests.isolate',
34     'cc_perftests': 'cc/cc_perftests.isolate',
35     'components_unittests': 'components/components_unittests.isolate',
36     'content_browsertests': 'content/content_browsertests.isolate',
37     'content_unittests': 'content/content_unittests.isolate',
38     'media_perftests': 'media/media_perftests.isolate',
39     'media_unittests': 'media/media_unittests.isolate',
40     'net_unittests': 'net/net_unittests.isolate',
41     'sql_unittests': 'sql/sql_unittests.isolate',
42     'ui_base_unittests': 'ui/base/ui_base_tests.isolate',
43     'ui_unittests': 'ui/base/ui_base_tests.isolate',
44     'unit_tests': 'chrome/unit_tests.isolate',
45     'webkit_unit_tests':
46       'third_party/WebKit/Source/web/WebKitUnitTests.isolate',
47 }
48
49 # Used for filtering large data deps at a finer grain than what's allowed in
50 # isolate files since pushing deps to devices is expensive.
51 # Wildcards are allowed.
52 _DEPS_EXCLUSION_LIST = [
53     'chrome/test/data/extensions/api_test',
54     'chrome/test/data/extensions/secure_shell',
55     'chrome/test/data/firefox*',
56     'chrome/test/data/gpu',
57     'chrome/test/data/image_decoding',
58     'chrome/test/data/import',
59     'chrome/test/data/page_cycler',
60     'chrome/test/data/perf',
61     'chrome/test/data/pyauto_private',
62     'chrome/test/data/safari_import',
63     'chrome/test/data/scroll',
64     'chrome/test/data/third_party',
65     'third_party/hunspell_dictionaries/*.dic',
66     # crbug.com/258690
67     'webkit/data/bmp_decoder',
68     'webkit/data/ico_decoder',
69 ]
70
71
72 def _GenerateDepsDirUsingIsolate(suite_name, isolate_file_path=None):
73   """Generate the dependency dir for the test suite using isolate.
74
75   Args:
76     suite_name: Name of the test suite (e.g. base_unittests).
77     isolate_file_path: .isolate file path to use. If there is a default .isolate
78                        file path for the suite_name, this will override it.
79   """
80   if isolate_file_path:
81     if os.path.isabs(isolate_file_path):
82       isolate_abs_path = isolate_file_path
83     else:
84       isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT,
85                                       isolate_file_path)
86   else:
87     isolate_rel_path = _ISOLATE_FILE_PATHS.get(suite_name)
88     if not isolate_rel_path:
89       logging.info('Did not find an isolate file for the test suite.')
90       return
91     isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, isolate_rel_path)
92
93   isolated_abs_path = os.path.join(
94       constants.GetOutDirectory(), '%s.isolated' % suite_name)
95   assert os.path.exists(isolate_abs_path), 'Cannot find %s' % isolate_abs_path
96
97   i = isolator.Isolator(constants.ISOLATE_DEPS_DIR)
98   i.Clear()
99   i.Remap(isolate_abs_path, isolated_abs_path)
100   # We're relying on the fact that timestamps are preserved
101   # by the remap command (hardlinked). Otherwise, all the data
102   # will be pushed to the device once we move to using time diff
103   # instead of md5sum. Perform a sanity check here.
104   i.VerifyHardlinks()
105   i.PurgeExcluded(_DEPS_EXCLUSION_LIST)
106   i.MoveOutputDeps()
107
108
109 def _GetDisabledTestsFilterFromFile(suite_name):
110   """Returns a gtest filter based on the *_disabled file.
111
112   Args:
113     suite_name: Name of the test suite (e.g. base_unittests).
114
115   Returns:
116     A gtest filter which excludes disabled tests.
117     Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc'
118   """
119   filter_file_path = os.path.join(
120       os.path.abspath(os.path.dirname(__file__)),
121       'filter', '%s_disabled' % suite_name)
122
123   if not filter_file_path or not os.path.exists(filter_file_path):
124     logging.info('No filter file found at %s', filter_file_path)
125     return '*'
126
127   filters = [x for x in [x.strip() for x in file(filter_file_path).readlines()]
128              if x and x[0] != '#']
129   disabled_filter = '*-%s' % ':'.join(filters)
130   logging.info('Applying filter "%s" obtained from %s',
131                disabled_filter, filter_file_path)
132   return disabled_filter
133
134
135 def _GetTests(test_options, test_package, devices):
136   """Get a list of tests.
137
138   Args:
139     test_options: A GTestOptions object.
140     test_package: A TestPackageApk object.
141     devices: A list of attached devices.
142
143   Returns:
144     A list of all the tests in the test suite.
145   """
146   class TestListResult(base_test_result.BaseTestResult):
147     def __init__(self):
148       super(TestListResult, self).__init__(
149           'gtest_list_tests', base_test_result.ResultType.PASS)
150       self.test_list = []
151
152   def TestListerRunnerFactory(device, _shard_index):
153     class TestListerRunner(test_runner.TestRunner):
154       def RunTest(self, _test):
155         result = TestListResult()
156         self.test_package.Install(self.device)
157         result.test_list = self.test_package.GetAllTests(self.device)
158         results = base_test_result.TestRunResults()
159         results.AddResult(result)
160         return results, None
161     return TestListerRunner(test_options, device, test_package)
162
163   results, _no_retry = test_dispatcher.RunTests(
164       ['gtest_list_tests'], TestListerRunnerFactory, devices)
165   tests = []
166   for r in results.GetAll():
167     tests.extend(r.test_list)
168   return tests
169
170
171 def _FilterTestsUsingPrefixes(all_tests, pre=False, manual=False):
172   """Removes tests with disabled prefixes.
173
174   Args:
175     all_tests: List of tests to filter.
176     pre: If True, include tests with PRE_ prefix.
177     manual: If True, include tests with MANUAL_ prefix.
178
179   Returns:
180     List of tests remaining.
181   """
182   filtered_tests = []
183   filter_prefixes = ['DISABLED_', 'FLAKY_', 'FAILS_']
184
185   if not pre:
186     filter_prefixes.append('PRE_')
187
188   if not manual:
189     filter_prefixes.append('MANUAL_')
190
191   for t in all_tests:
192     test_case, test = t.split('.', 1)
193     if not any([test_case.startswith(prefix) or test.startswith(prefix) for
194                 prefix in filter_prefixes]):
195       filtered_tests.append(t)
196   return filtered_tests
197
198
199 def _FilterDisabledTests(tests, suite_name, has_gtest_filter):
200   """Removes disabled tests from |tests|.
201
202   Applies the following filters in order:
203     1. Remove tests with disabled prefixes.
204     2. Remove tests specified in the *_disabled files in the 'filter' dir
205
206   Args:
207     tests: List of tests.
208     suite_name: Name of the test suite (e.g. base_unittests).
209     has_gtest_filter: Whether a gtest_filter is provided.
210
211   Returns:
212     List of tests remaining.
213   """
214   tests = _FilterTestsUsingPrefixes(
215       tests, has_gtest_filter, has_gtest_filter)
216   tests = unittest_util.FilterTestNames(
217       tests, _GetDisabledTestsFilterFromFile(suite_name))
218
219   return tests
220
221
222 def PushDataDeps(device, test_options, test_package):
223   valgrind_tools.PushFilesForTool(test_options.tool, device)
224   if os.path.exists(constants.ISOLATE_DEPS_DIR):
225     device_dir = (
226         constants.TEST_EXECUTABLE_DIR
227         if test_package.suite_name == 'breakpad_unittests'
228         else device.GetExternalStoragePath())
229     device.PushChangedFiles([
230         (os.path.join(constants.ISOLATE_DEPS_DIR, p),
231          '%s/%s' % (device_dir, p))
232         for p in os.listdir(constants.ISOLATE_DEPS_DIR)])
233
234
235 def Setup(test_options, devices):
236   """Create the test runner factory and tests.
237
238   Args:
239     test_options: A GTestOptions object.
240     devices: A list of attached devices.
241
242   Returns:
243     A tuple of (TestRunnerFactory, tests).
244   """
245   test_package = test_package_apk.TestPackageApk(test_options.suite_name)
246   if not os.path.exists(test_package.suite_path):
247     exe_test_package = test_package_exe.TestPackageExecutable(
248         test_options.suite_name)
249     if not os.path.exists(exe_test_package.suite_path):
250       raise Exception(
251           'Did not find %s target. Ensure it has been built.\n'
252           '(not found at %s or %s)'
253           % (test_options.suite_name,
254              test_package.suite_path,
255              exe_test_package.suite_path))
256     test_package = exe_test_package
257   logging.warning('Found target %s', test_package.suite_path)
258
259   _GenerateDepsDirUsingIsolate(test_options.suite_name,
260                                test_options.isolate_file_path)
261
262   device_utils.DeviceUtils.parallel(devices).pMap(
263       PushDataDeps, test_options, test_package)
264
265   tests = _GetTests(test_options, test_package, devices)
266
267   # Constructs a new TestRunner with the current options.
268   def TestRunnerFactory(device, _shard_index):
269     return test_runner.TestRunner(
270         test_options,
271         device,
272         test_package)
273
274   if test_options.run_disabled:
275     test_options = test_options._replace(
276         test_arguments=('%s --gtest_also_run_disabled_tests' %
277                         test_options.test_arguments))
278   else:
279     tests = _FilterDisabledTests(tests, test_options.suite_name,
280                                  bool(test_options.gtest_filter))
281   if test_options.gtest_filter:
282     tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter)
283
284   # Coalesce unit tests into a single test per device
285   if test_options.suite_name != 'content_browsertests':
286     num_devices = len(devices)
287     tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)]
288     tests = [t for t in tests if t]
289
290   return (TestRunnerFactory, tests)