blob: e9bf3cf479846c2f94495b65cc37e45f43a71bce [file] [log] [blame]
jbudorick27e6905f2014-12-03 23:27:481# Copyright 2014 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
jbudorick5cea02e2016-09-23 17:06:165import HTMLParser
jbudorick27e6905f2014-12-03 23:27:486import logging
7import os
jbudorick8f495282014-12-15 22:23:298import re
jbudorick5ee45892015-06-10 18:46:229import tempfile
mikecasec37f55c2016-11-18 20:59:2210import threading
jbudorick5cea02e2016-09-23 17:06:1611import xml.etree.ElementTree
jbudorick27e6905f2014-12-03 23:27:4812
jbudorick061629442015-09-03 18:00:5713from devil.android import apk_helper
jbudorick27e6905f2014-12-03 23:27:4814from pylib import constants
jbudorickd28554a2016-01-11 16:22:5915from pylib.constants import host_paths
jbudorick8f495282014-12-15 22:23:2916from pylib.base import base_test_result
jbudorick27e6905f2014-12-03 23:27:4817from pylib.base import test_instance
Zhiling Huang4e9529db2017-09-01 21:55:2418from pylib.symbols import stack_symbolizer
jbudorick27e6905f2014-12-03 23:27:4819
jbudorickd28554a2016-01-11 16:22:5920with host_paths.SysPath(host_paths.BUILD_COMMON_PATH):
21 import unittest_util # pylint: disable=import-error
jbudorick27e6905f2014-12-03 23:27:4822
23
jbudorick08b097a932015-05-22 02:54:5724BROWSER_TEST_SUITES = [
25 'components_browsertests',
26 'content_browsertests',
27]
28
jcivellif4462a352017-01-10 04:45:5929RUN_IN_SUB_THREAD_TEST_SUITES = [
30 # Multiprocess tests should be run outside of the main thread.
31 'base_unittests', # file_locking_unittest.cc uses a child process.
32 'ipc_perftests',
33 'ipc_tests',
Oksana Zhuravlova32f0a132018-02-27 00:12:5534 'mojo_perftests',
Oksana Zhuravlova1792d19f2018-02-22 19:13:3135 'mojo_unittests',
jcivellif4462a352017-01-10 04:45:5936 'net_unittests'
37]
jbudorick566592ab2015-09-21 15:32:4738
jbudorick08b097a932015-05-22 02:54:5739
jbudorick27e6905f2014-12-03 23:27:4840# Used for filtering large data deps at a finer grain than what's allowed in
41# isolate files since pushing deps to devices is expensive.
42# Wildcards are allowed.
43_DEPS_EXCLUSION_LIST = [
44 'chrome/test/data/extensions/api_test',
45 'chrome/test/data/extensions/secure_shell',
46 'chrome/test/data/firefox*',
47 'chrome/test/data/gpu',
48 'chrome/test/data/image_decoding',
49 'chrome/test/data/import',
50 'chrome/test/data/page_cycler',
51 'chrome/test/data/perf',
52 'chrome/test/data/pyauto_private',
53 'chrome/test/data/safari_import',
54 'chrome/test/data/scroll',
55 'chrome/test/data/third_party',
56 'third_party/hunspell_dictionaries/*.dic',
57 # crbug.com/258690
58 'webkit/data/bmp_decoder',
59 'webkit/data/ico_decoder',
60]
61
62
jbudorick590a3d72015-06-12 23:53:3163_EXTRA_NATIVE_TEST_ACTIVITY = (
64 'org.chromium.native_test.NativeTestInstrumentationTestRunner.'
65 'NativeTestActivity')
jbudorick566592ab2015-09-21 15:32:4766_EXTRA_RUN_IN_SUB_THREAD = (
ynovikov389d9e442016-05-27 02:34:5667 'org.chromium.native_test.NativeTest.RunInSubThread')
jbudorick6ef3cbd2015-09-30 09:04:1968EXTRA_SHARD_NANO_TIMEOUT = (
69 'org.chromium.native_test.NativeTestInstrumentationTestRunner.'
70 'ShardNanoTimeout')
jbudorick58b4d362015-09-08 16:44:5971_EXTRA_SHARD_SIZE_LIMIT = (
jbudorick590a3d72015-06-12 23:53:3172 'org.chromium.native_test.NativeTestInstrumentationTestRunner.'
73 'ShardSizeLimit')
74
jbudorick8f495282014-12-15 22:23:2975# TODO(jbudorick): Remove these once we're no longer parsing stdout to generate
76# results.
77_RE_TEST_STATUS = re.compile(
hzl09361b72016-03-09 00:00:1578 r'\[ +((?:RUN)|(?:FAILED)|(?:OK)|(?:CRASHED)) +\]'
79 r' ?([^ ]+)?(?: \((\d+) ms\))?$')
hzl09361b72016-03-09 00:00:1580# Crash detection constants.
81_RE_TEST_ERROR = re.compile(r'FAILURES!!! Tests run: \d+,'
82 r' Failures: \d+, Errors: 1')
83_RE_TEST_CURRENTLY_RUNNING = re.compile(r'\[ERROR:.*?\]'
84 r' Currently running: (.*)')
shenghuazhang61757ce2016-12-08 22:53:0185_RE_DISABLED = re.compile(r'DISABLED_')
86_RE_FLAKY = re.compile(r'FLAKY_')
jbudorick8f495282014-12-15 22:23:2987
Zhiling Huang4e9529db2017-09-01 21:55:2488# Detect stack line in stdout.
89_STACK_LINE_RE = re.compile(r'\s*#\d+')
90
jbudorick8f495282014-12-15 22:23:2991def ParseGTestListTests(raw_list):
92 """Parses a raw test list as provided by --gtest_list_tests.
93
94 Args:
95 raw_list: The raw test listing with the following format:
96
97 IPCChannelTest.
98 SendMessageInChannelConnected
99 IPCSyncChannelTest.
100 Simple
101 DISABLED_SendWithTimeoutMixedOKAndTimeout
102
103 Returns:
104 A list of all tests. For the above raw listing:
105
106 [IPCChannelTest.SendMessageInChannelConnected, IPCSyncChannelTest.Simple,
107 IPCSyncChannelTest.DISABLED_SendWithTimeoutMixedOKAndTimeout]
108 """
109 ret = []
110 current = ''
111 for test in raw_list:
112 if not test:
113 continue
jbudorickef60bcc92016-12-19 18:33:07114 if not test.startswith(' '):
jbudorick8f495282014-12-15 22:23:29115 test_case = test.split()[0]
116 if test_case.endswith('.'):
117 current = test_case
jbudorickef60bcc92016-12-19 18:33:07118 else:
119 test = test.strip()
120 if test and not 'YOU HAVE' in test:
121 test_name = test.split()[0]
122 ret += [current + test_name]
jbudorick8f495282014-12-15 22:23:29123 return ret
124
125
Zhiling Huang4e9529db2017-09-01 21:55:24126def ParseGTestOutput(output, symbolizer, device_abi):
jbudorickf7461112016-05-27 04:30:49127 """Parses raw gtest output and returns a list of results.
128
129 Args:
130 output: A list of output lines.
Zhiling Huang4e9529db2017-09-01 21:55:24131 symbolizer: The symbolizer used to symbolize stack.
132 device_abi: Device abi that is needed for symbolization.
jbudorickf7461112016-05-27 04:30:49133 Returns:
134 A list of base_test_result.BaseTestResults.
135 """
John Budorickc4f40732016-07-12 18:13:59136 duration = 0
137 fallback_result_type = None
jbudorickf7461112016-05-27 04:30:49138 log = []
Zhiling Huang4e9529db2017-09-01 21:55:24139 stack = []
jbudorickf7461112016-05-27 04:30:49140 result_type = None
141 results = []
142 test_name = None
143
Zhiling Huang4e9529db2017-09-01 21:55:24144 def symbolize_stack_and_merge_with_log():
145 log_string = '\n'.join(log or [])
146 if not stack:
147 stack_string = ''
148 else:
149 stack_string = '\n'.join(
150 symbolizer.ExtractAndResolveNativeStackTraces(
151 stack, device_abi))
152 return '%s\n%s' % (log_string, stack_string)
153
jbudorickf7461112016-05-27 04:30:49154 def handle_possibly_unknown_test():
155 if test_name is not None:
156 results.append(base_test_result.BaseTestResult(
shenghuazhangd0287a22017-03-15 18:57:31157 TestNameWithoutDisabledPrefix(test_name),
John Budorickc4f40732016-07-12 18:13:59158 fallback_result_type or base_test_result.ResultType.UNKNOWN,
Zhiling Huang4e9529db2017-09-01 21:55:24159 duration, log=symbolize_stack_and_merge_with_log()))
jbudorickf7461112016-05-27 04:30:49160
161 for l in output:
jbudorickf7461112016-05-27 04:30:49162 matcher = _RE_TEST_STATUS.match(l)
163 if matcher:
164 if matcher.group(1) == 'RUN':
165 handle_possibly_unknown_test()
John Budorickc4f40732016-07-12 18:13:59166 duration = 0
167 fallback_result_type = None
jbudorickf7461112016-05-27 04:30:49168 log = []
Zhiling Huang4e9529db2017-09-01 21:55:24169 stack = []
John Budorickc4f40732016-07-12 18:13:59170 result_type = None
jbudorickf7461112016-05-27 04:30:49171 elif matcher.group(1) == 'OK':
172 result_type = base_test_result.ResultType.PASS
173 elif matcher.group(1) == 'FAILED':
174 result_type = base_test_result.ResultType.FAIL
175 elif matcher.group(1) == 'CRASHED':
John Budorickc4f40732016-07-12 18:13:59176 fallback_result_type = base_test_result.ResultType.CRASH
jbudorickf7461112016-05-27 04:30:49177 # Be aware that test name and status might not appear on same line.
178 test_name = matcher.group(2) if matcher.group(2) else test_name
179 duration = int(matcher.group(3)) if matcher.group(3) else 0
180
181 else:
182 # Needs another matcher here to match crashes, like those of DCHECK.
183 matcher = _RE_TEST_CURRENTLY_RUNNING.match(l)
184 if matcher:
185 test_name = matcher.group(1)
186 result_type = base_test_result.ResultType.CRASH
187 duration = 0 # Don't know.
188
189 if log is not None:
Zhiling Huangb73321e52017-09-06 21:51:38190 if not matcher and _STACK_LINE_RE.match(l):
Zhiling Huang4e9529db2017-09-01 21:55:24191 stack.append(l)
192 else:
193 log.append(l)
jbudorickf7461112016-05-27 04:30:49194
jbudorick244896c2016-05-31 23:35:06195 if result_type and test_name:
Benjamin Pastened3fca322018-01-05 21:05:44196 # Don't bother symbolizing output if the test passed.
197 if result_type == base_test_result.ResultType.PASS:
198 stack = []
jbudorickf7461112016-05-27 04:30:49199 results.append(base_test_result.BaseTestResult(
shenghuazhangd0287a22017-03-15 18:57:31200 TestNameWithoutDisabledPrefix(test_name), result_type, duration,
Zhiling Huang4e9529db2017-09-01 21:55:24201 log=symbolize_stack_and_merge_with_log()))
jbudorickf7461112016-05-27 04:30:49202 test_name = None
203
204 handle_possibly_unknown_test()
205
206 return results
207
208
jbudorick5cea02e2016-09-23 17:06:16209def ParseGTestXML(xml_content):
210 """Parse gtest XML result."""
211 results = []
John Budorick79cd156c2017-09-15 21:23:28212 if not xml_content:
213 return results
jbudorick5cea02e2016-09-23 17:06:16214
215 html = HTMLParser.HTMLParser()
216
jbudorick5cea02e2016-09-23 17:06:16217 testsuites = xml.etree.ElementTree.fromstring(xml_content)
218 for testsuite in testsuites:
219 suite_name = testsuite.attrib['name']
220 for testcase in testsuite:
221 case_name = testcase.attrib['name']
222 result_type = base_test_result.ResultType.PASS
223 log = []
224 for failure in testcase:
225 result_type = base_test_result.ResultType.FAIL
226 log.append(html.unescape(failure.attrib['message']))
227
228 results.append(base_test_result.BaseTestResult(
shenghuazhangd0287a22017-03-15 18:57:31229 '%s.%s' % (suite_name, TestNameWithoutDisabledPrefix(case_name)),
jbudorick5cea02e2016-09-23 17:06:16230 result_type,
231 int(float(testcase.attrib['time']) * 1000),
232 log=('\n'.join(log) if log else '')))
233
234 return results
235
236
lukasza1f3f8c662016-11-08 16:53:56237def ConvertTestFilterFileIntoGTestFilterArgument(input_lines):
238 """Converts test filter file contents into --gtest_filter argument.
239
240 See //testing/buildbot/filters/README.md for description of the
241 syntax that |input_lines| are expected to follow.
242
243 See
244 https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#running-a-subset-of-the-tests
245 for description of the syntax that --gtest_filter argument should follow.
246
247 Args:
248 input_lines: An iterable (e.g. a list or a file) containing input lines.
249 Returns:
250 a string suitable for feeding as an argument of --gtest_filter parameter.
251 """
Sergey Ulanov3d567ae2017-08-26 02:11:54252 # Strip comments and whitespace from each line and filter non-empty lines.
253 stripped_lines = (l.split('#', 1)[0].strip() for l in input_lines)
254 filter_lines = list(l for l in stripped_lines if l)
lukasza1f3f8c662016-11-08 16:53:56255
256 # Split the tests into positive and negative patterns (gtest treats
257 # every pattern after the first '-' sign as an exclusion).
258 positive_patterns = ':'.join(l for l in filter_lines if l[0] != '-')
259 negative_patterns = ':'.join(l[1:] for l in filter_lines if l[0] == '-')
260 if negative_patterns:
261 negative_patterns = '-' + negative_patterns
262
263 # Join the filter lines into one, big --gtest_filter argument.
264 return positive_patterns + negative_patterns
265
shenghuazhang61757ce2016-12-08 22:53:01266def TestNameWithoutDisabledPrefix(test_name):
267 """Modify the test name without disabled prefix if prefix 'DISABLED_' or
268 'FLAKY_' presents.
269
270 Args:
271 test_name: The name of a test.
272 Returns:
273 A test name without prefix 'DISABLED_' or 'FLAKY_'.
274 """
275 disabled_prefixes = [_RE_DISABLED, _RE_FLAKY]
276 for dp in disabled_prefixes:
277 test_name = dp.sub('', test_name)
278 return test_name
lukasza1f3f8c662016-11-08 16:53:56279
jbudorick27e6905f2014-12-03 23:27:48280class GtestTestInstance(test_instance.TestInstance):
281
jbudorickd29ecfa72016-11-18 22:45:42282 def __init__(self, args, data_deps_delegate, error_func):
jbudorick27e6905f2014-12-03 23:27:48283 super(GtestTestInstance, self).__init__()
rnephew5c499782014-12-12 19:08:55284 # TODO(jbudorick): Support multiple test suites.
jbudorick8f495282014-12-15 22:23:29285 if len(args.suite_name) > 1:
rnephew5c499782014-12-12 19:08:55286 raise ValueError('Platform mode currently supports only 1 gtest suite')
Edward Lemure627ef82017-12-13 13:00:33287 self._chartjson_result_file = args.chartjson_result_file
hzl19e0bee72016-11-15 01:14:22288 self._exe_dist_dir = None
jbudorick84188b52017-03-15 05:29:24289 self._external_shard_index = args.test_launcher_shard_index
agrieve0f5e53e2016-02-04 03:47:37290 self._extract_test_list_from_filter = args.extract_test_list_from_filter
jbudorick84188b52017-03-15 05:29:24291 self._filter_tests_lock = threading.Lock()
Edward Lemure627ef82017-12-13 13:00:33292 self._gs_test_artifacts_bucket = args.gs_test_artifacts_bucket
jbudorick24616eb2015-10-06 02:40:57293 self._shard_timeout = args.shard_timeout
hzl19e0bee72016-11-15 01:14:22294 self._store_tombstones = args.store_tombstones
agrieve0f5e53e2016-02-04 03:47:37295 self._suite = args.suite_name[0]
Zhiling Huang4e9529db2017-09-01 21:55:24296 self._symbolizer = stack_symbolizer.Symbolizer(None, False)
Edward Lemure627ef82017-12-13 13:00:33297 self._total_external_shards = args.test_launcher_total_shards
Andrew Grieve0904ce152017-10-03 21:09:12298 self._wait_for_java_debugger = args.wait_for_java_debugger
jbudorick24616eb2015-10-06 02:40:57299
agrieve62ab00282016-04-05 02:03:45300 # GYP:
301 if args.executable_dist_dir:
302 self._exe_dist_dir = os.path.abspath(args.executable_dist_dir)
303 else:
304 # TODO(agrieve): Remove auto-detection once recipes pass flag explicitly.
305 exe_dist_dir = os.path.join(constants.GetOutDirectory(),
306 '%s__dist' % self._suite)
307
308 if os.path.exists(exe_dist_dir):
309 self._exe_dist_dir = exe_dist_dir
agrieve4931af8c2016-02-10 19:25:26310
311 incremental_part = ''
Andrew Grieve2ec70f32017-08-11 20:47:43312 if args.test_apk_incremental_install_json:
agrieve4931af8c2016-02-10 19:25:26313 incremental_part = '_incremental'
314
agrieve7c7f0802015-10-09 19:08:50315 apk_path = os.path.join(
jbudorick08b097a932015-05-22 02:54:57316 constants.GetOutDirectory(), '%s_apk' % self._suite,
agrieve1a02e582015-10-15 21:35:39317 '%s-debug%s.apk' % (self._suite, incremental_part))
Andrew Grieve2ec70f32017-08-11 20:47:43318 self._test_apk_incremental_install_json = (
319 args.test_apk_incremental_install_json)
agrieve7c7f0802015-10-09 19:08:50320 if not os.path.exists(apk_path):
321 self._apk_helper = None
jbudorick590a3d72015-06-12 23:53:31322 else:
agrieve7c7f0802015-10-09 19:08:50323 self._apk_helper = apk_helper.ApkHelper(apk_path)
jbudorick590a3d72015-06-12 23:53:31324 self._extras = {
agrieve7c7f0802015-10-09 19:08:50325 _EXTRA_NATIVE_TEST_ACTIVITY: self._apk_helper.GetActivityName(),
jbudorick590a3d72015-06-12 23:53:31326 }
jbudorick566592ab2015-09-21 15:32:47327 if self._suite in RUN_IN_SUB_THREAD_TEST_SUITES:
328 self._extras[_EXTRA_RUN_IN_SUB_THREAD] = 1
jbudorick590a3d72015-06-12 23:53:31329 if self._suite in BROWSER_TEST_SUITES:
330 self._extras[_EXTRA_SHARD_SIZE_LIMIT] = 1
jbudorick24616eb2015-10-06 02:40:57331 self._extras[EXTRA_SHARD_NANO_TIMEOUT] = int(1e9 * self._shard_timeout)
jbudorick8932b412016-05-19 17:52:23332 self._shard_timeout = 10 * self._shard_timeout
Andrew Grieve0904ce152017-10-03 21:09:12333 if args.wait_for_java_debugger:
334 self._extras[EXTRA_SHARD_NANO_TIMEOUT] = int(1e15) # Forever
jbudorick590a3d72015-06-12 23:53:31335
agrieve62ab00282016-04-05 02:03:45336 if not self._apk_helper and not self._exe_dist_dir:
jbudorick8f495282014-12-15 22:23:29337 error_func('Could not find apk or executable for %s' % self._suite)
338
jbudorick27e6905f2014-12-03 23:27:48339 self._data_deps = []
jbudorick442a6932015-02-03 03:01:15340 if args.test_filter:
341 self._gtest_filter = args.test_filter
342 elif args.test_filter_file:
343 with open(args.test_filter_file, 'r') as f:
lukasza1f3f8c662016-11-08 16:53:56344 self._gtest_filter = ConvertTestFilterFileIntoGTestFilterArgument(f)
jbudorick442a6932015-02-03 03:01:15345 else:
346 self._gtest_filter = None
jbudorick590a3d72015-06-12 23:53:31347
shenghuazhangb58f48f42016-12-01 01:50:34348 self._run_disabled = args.run_disabled
349
jbudorickd29ecfa72016-11-18 22:45:42350 self._data_deps_delegate = data_deps_delegate
351 self._runtime_deps_path = args.runtime_deps_path
352 if not self._runtime_deps_path:
353 logging.warning('No data dependencies will be pushed.')
jbudorick27e6905f2014-12-03 23:27:48354
jbudorick5ee45892015-06-10 18:46:22355 if args.app_data_files:
356 self._app_data_files = args.app_data_files
357 if args.app_data_file_dir:
358 self._app_data_file_dir = args.app_data_file_dir
359 else:
360 self._app_data_file_dir = tempfile.mkdtemp()
361 logging.critical('Saving app files to %s', self._app_data_file_dir)
362 else:
363 self._app_data_files = None
364 self._app_data_file_dir = None
365
jbudorick7d30806c2017-03-16 19:18:52366 self._flags = None
367 self._initializeCommandLineFlags(args)
jbudoricka58ea512015-10-20 14:36:58368
jbudorick5cea02e2016-09-23 17:06:16369 # TODO(jbudorick): Remove this once it's deployed.
370 self._enable_xml_result_parsing = args.enable_xml_result_parsing
371
jbudorick7d30806c2017-03-16 19:18:52372 def _initializeCommandLineFlags(self, args):
373 self._flags = []
374 if args.command_line_flags:
375 self._flags.extend(args.command_line_flags)
376 if args.device_flags_file:
377 with open(args.device_flags_file) as f:
378 stripped_lines = (l.strip() for l in f)
379 self._flags.extend(flag for flag in stripped_lines if flag)
380 if args.run_disabled:
381 self._flags.append('--gtest_also_run_disabled_tests')
jbudorick7d30806c2017-03-16 19:18:52382
jbudoricka58ea512015-10-20 14:36:58383 @property
384 def activity(self):
385 return self._apk_helper and self._apk_helper.GetActivityName()
386
387 @property
388 def apk(self):
389 return self._apk_helper and self._apk_helper.path
390
391 @property
392 def apk_helper(self):
393 return self._apk_helper
394
395 @property
396 def app_file_dir(self):
397 return self._app_data_file_dir
398
399 @property
400 def app_files(self):
401 return self._app_data_files
402
403 @property
jbudorick5cea02e2016-09-23 17:06:16404 def enable_xml_result_parsing(self):
405 return self._enable_xml_result_parsing
406
407 @property
agrieve62ab00282016-04-05 02:03:45408 def exe_dist_dir(self):
409 return self._exe_dist_dir
jbudoricka58ea512015-10-20 14:36:58410
411 @property
jbudorick84188b52017-03-15 05:29:24412 def external_shard_index(self):
413 return self._external_shard_index
414
415 @property
416 def extract_test_list_from_filter(self):
417 return self._extract_test_list_from_filter
418
419 @property
jbudoricka58ea512015-10-20 14:36:58420 def extras(self):
421 return self._extras
422
agrieve065d7462015-10-13 23:23:36423 @property
jbudorick7d30806c2017-03-16 19:18:52424 def flags(self):
425 return self._flags
shenghuazhangb58f48f42016-12-01 01:50:34426
427 @property
Edward Lemur29acd732017-09-26 15:20:04428 def gs_test_artifacts_bucket(self):
429 return self._gs_test_artifacts_bucket
430
431 @property
agrieve065d7462015-10-13 23:23:36432 def gtest_filter(self):
433 return self._gtest_filter
434
jbudoricka58ea512015-10-20 14:36:58435 @property
Edward Lemure627ef82017-12-13 13:00:33436 def chartjson_result_file(self):
437 return self._chartjson_result_file
438
439 @property
jbudoricka58ea512015-10-20 14:36:58440 def package(self):
441 return self._apk_helper and self._apk_helper.GetPackageName()
442
443 @property
444 def permissions(self):
445 return self._apk_helper and self._apk_helper.GetPermissions()
446
447 @property
448 def runner(self):
449 return self._apk_helper and self._apk_helper.GetInstrumentationName()
450
451 @property
452 def shard_timeout(self):
453 return self._shard_timeout
454
455 @property
hzl19e0bee72016-11-15 01:14:22456 def store_tombstones(self):
457 return self._store_tombstones
458
459 @property
jbudoricka58ea512015-10-20 14:36:58460 def suite(self):
461 return self._suite
462
463 @property
Zhiling Huang4e9529db2017-09-01 21:55:24464 def symbolizer(self):
465 return self._symbolizer
466
467 @property
Andrew Grieve2ec70f32017-08-11 20:47:43468 def test_apk_incremental_install_json(self):
469 return self._test_apk_incremental_install_json
agrieve4931af8c2016-02-10 19:25:26470
471 @property
jbudorick84188b52017-03-15 05:29:24472 def total_external_shards(self):
473 return self._total_external_shards
agrieve0f5e53e2016-02-04 03:47:37474
Andrew Grieve0904ce152017-10-03 21:09:12475 @property
476 def wait_for_java_debugger(self):
477 return self._wait_for_java_debugger
478
jbudorick27e6905f2014-12-03 23:27:48479 #override
480 def TestType(self):
481 return 'gtest'
482
483 #override
484 def SetUp(self):
485 """Map data dependencies via isolate."""
jbudorickd29ecfa72016-11-18 22:45:42486 self._data_deps.extend(
487 self._data_deps_delegate(self._runtime_deps_path))
jbudorick27e6905f2014-12-03 23:27:48488
489 def GetDataDependencies(self):
490 """Returns the test suite's data dependencies.
491
492 Returns:
493 A list of (host_path, device_path) tuples to push. If device_path is
494 None, the client is responsible for determining where to push the file.
495 """
496 return self._data_deps
497
498 def FilterTests(self, test_list, disabled_prefixes=None):
499 """Filters |test_list| based on prefixes and, if present, a filter string.
500
501 Args:
502 test_list: The list of tests to filter.
503 disabled_prefixes: A list of test prefixes to filter. Defaults to
504 DISABLED_, FLAKY_, FAILS_, PRE_, and MANUAL_
505 Returns:
506 A filtered list of tests to run.
507 """
508 gtest_filter_strings = [
509 self._GenerateDisabledFilterString(disabled_prefixes)]
510 if self._gtest_filter:
511 gtest_filter_strings.append(self._gtest_filter)
512
513 filtered_test_list = test_list
mikecasec37f55c2016-11-18 20:59:22514 # This lock is required because on older versions of Python
515 # |unittest_util.FilterTestNames| use of |fnmatch| is not threadsafe.
516 with self._filter_tests_lock:
517 for gtest_filter_string in gtest_filter_strings:
518 logging.debug('Filtering tests using: %s', gtest_filter_string)
519 filtered_test_list = unittest_util.FilterTestNames(
520 filtered_test_list, gtest_filter_string)
shenghuazhang61757ce2016-12-08 22:53:01521
522 if self._run_disabled and self._gtest_filter:
523 out_filtered_test_list = list(set(test_list)-set(filtered_test_list))
524 for test in out_filtered_test_list:
525 test_name_no_disabled = TestNameWithoutDisabledPrefix(test)
526 if test_name_no_disabled != test and unittest_util.FilterTestNames(
527 [test_name_no_disabled], self._gtest_filter):
528 filtered_test_list.append(test)
jbudorick27e6905f2014-12-03 23:27:48529 return filtered_test_list
530
531 def _GenerateDisabledFilterString(self, disabled_prefixes):
532 disabled_filter_items = []
533
534 if disabled_prefixes is None:
shenghuazhangb58f48f42016-12-01 01:50:34535 disabled_prefixes = ['FAILS_', 'PRE_', 'MANUAL_']
536 if not self._run_disabled:
537 disabled_prefixes += ['DISABLED_', 'FLAKY_']
538
jbudorick27e6905f2014-12-03 23:27:48539 disabled_filter_items += ['%s*' % dp for dp in disabled_prefixes]
jbudorick8f495282014-12-15 22:23:29540 disabled_filter_items += ['*.%s*' % dp for dp in disabled_prefixes]
jbudorick27e6905f2014-12-03 23:27:48541
542 disabled_tests_file_path = os.path.join(
jbudorickd28554a2016-01-11 16:22:59543 host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'pylib', 'gtest',
jbudorick27e6905f2014-12-03 23:27:48544 'filter', '%s_disabled' % self._suite)
545 if disabled_tests_file_path and os.path.exists(disabled_tests_file_path):
546 with open(disabled_tests_file_path) as disabled_tests_file:
547 disabled_filter_items += [
548 '%s' % l for l in (line.strip() for line in disabled_tests_file)
549 if l and not l.startswith('#')]
550
551 return '*-%s' % ':'.join(disabled_filter_items)
552
553 #override
554 def TearDown(self):
jbudorickd29ecfa72016-11-18 22:45:42555 """Do nothing."""
556 pass
jbudorick27e6905f2014-12-03 23:27:48557