Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import logging | 5 import logging |
| 6 import os | 6 import os |
| 7 import re | 7 import re |
| 8 import tempfile | 8 import tempfile |
| 9 | 9 |
| 10 from devil.android import apk_helper | 10 from devil.android import apk_helper |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 self._app_data_file_dir = args.app_data_file_dir | 199 self._app_data_file_dir = args.app_data_file_dir |
| 200 else: | 200 else: |
| 201 self._app_data_file_dir = tempfile.mkdtemp() | 201 self._app_data_file_dir = tempfile.mkdtemp() |
| 202 logging.critical('Saving app files to %s', self._app_data_file_dir) | 202 logging.critical('Saving app files to %s', self._app_data_file_dir) |
| 203 else: | 203 else: |
| 204 self._app_data_files = None | 204 self._app_data_files = None |
| 205 self._app_data_file_dir = None | 205 self._app_data_file_dir = None |
| 206 | 206 |
| 207 self._test_arguments = args.test_arguments | 207 self._test_arguments = args.test_arguments |
| 208 | 208 |
| 209 # Crash detection constants. | |
| 210 self._TEST_ERROR_RE = re.compile(r'FAILURES!!! Tests run: \d+,' | |
|
jbudorick
2016/03/01 05:05:26
not class-scope constants, top level module-scope
| |
| 211 r' Failures: \d+, Errors: 1') | |
| 212 self._TEST_CURRENTLY_RUNNING_RE = re.compile(r'\[ERROR:.*?\]' | |
| 213 r' Currently running: (.*)') | |
| 214 self._TEST_RUN_RE = re.compile(r'\[ RUN \] (.*)') | |
| 215 self._TEST_CRASH_TAG = '[ CRASHED ]' | |
| 216 | |
| 209 @property | 217 @property |
| 210 def activity(self): | 218 def activity(self): |
| 211 return self._apk_helper and self._apk_helper.GetActivityName() | 219 return self._apk_helper and self._apk_helper.GetActivityName() |
| 212 | 220 |
| 213 @property | 221 @property |
| 214 def apk(self): | 222 def apk(self): |
| 215 return self._apk_helper and self._apk_helper.path | 223 return self._apk_helper and self._apk_helper.path |
| 216 | 224 |
| 217 @property | 225 @property |
| 218 def apk_helper(self): | 226 def apk_helper(self): |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'pylib', 'gtest', | 344 host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'pylib', 'gtest', |
| 337 'filter', '%s_disabled' % self._suite) | 345 'filter', '%s_disabled' % self._suite) |
| 338 if disabled_tests_file_path and os.path.exists(disabled_tests_file_path): | 346 if disabled_tests_file_path and os.path.exists(disabled_tests_file_path): |
| 339 with open(disabled_tests_file_path) as disabled_tests_file: | 347 with open(disabled_tests_file_path) as disabled_tests_file: |
| 340 disabled_filter_items += [ | 348 disabled_filter_items += [ |
| 341 '%s' % l for l in (line.strip() for line in disabled_tests_file) | 349 '%s' % l for l in (line.strip() for line in disabled_tests_file) |
| 342 if l and not l.startswith('#')] | 350 if l and not l.startswith('#')] |
| 343 | 351 |
| 344 return '*-%s' % ':'.join(disabled_filter_items) | 352 return '*-%s' % ':'.join(disabled_filter_items) |
| 345 | 353 |
| 354 def GetCrashedTestCase(self, output): | |
| 355 crash_happened = self._TEST_ERROR_RE.search(output[-1]) | |
| 356 if not crash_happened: | |
| 357 return | |
| 358 # Crashes that will cause output like DCHECK(false). | |
| 359 has_crash = self._TEST_CURRENTLY_RUNNING_RE.search(output[-3]) | |
|
jbudorick
2016/03/01 05:05:26
Can we either document this -3 or check for _TEST_
| |
| 360 if has_crash: | |
| 361 return has_crash.group(1) | |
| 362 | |
| 363 # Crashes that will cause output like null pointer dereference. | |
| 364 index = -1 if not self._TEST_CRASH_TAG in output \ | |
|
jbudorick
2016/03/01 05:05:26
Do we need to check all of output for _TEST_CRASH_
| |
| 365 else output.index(self._TEST_CRASH_TAG) | |
| 366 if not index == -1: | |
| 367 run_info = self._TEST_RUN_RE.search(output[index-1]) | |
|
jbudorick
2016/03/01 05:05:26
I think this should scan up until it finds a match
| |
| 368 if run_info: | |
| 369 return run_info.group(1) | |
| 370 | |
| 346 # pylint: disable=no-self-use | 371 # pylint: disable=no-self-use |
| 347 def ParseGTestOutput(self, output): | 372 def ParseGTestOutput(self, output): |
| 348 """Parses raw gtest output and returns a list of results. | 373 """Parses raw gtest output and returns a list of results. |
| 349 | 374 |
| 350 Args: | 375 Args: |
| 351 output: A list of output lines. | 376 output: A list of output lines. |
| 352 Returns: | 377 Returns: |
| 353 A list of base_test_result.BaseTestResults. | 378 A list of base_test_result.BaseTestResults. |
| 354 """ | 379 """ |
| 355 log = [] | 380 log = [] |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 370 log.append(l) | 395 log.append(l) |
| 371 | 396 |
| 372 if result_type: | 397 if result_type: |
| 373 test_name = matcher.group(2) | 398 test_name = matcher.group(2) |
| 374 duration = int(matcher.group(3)) if matcher.group(3) else 0 | 399 duration = int(matcher.group(3)) if matcher.group(3) else 0 |
| 375 results.append(base_test_result.BaseTestResult( | 400 results.append(base_test_result.BaseTestResult( |
| 376 test_name, result_type, duration, | 401 test_name, result_type, duration, |
| 377 log=('\n'.join(log) if log else ''))) | 402 log=('\n'.join(log) if log else ''))) |
| 378 log = None | 403 log = None |
| 379 result_type = None | 404 result_type = None |
| 380 | 405 crashed_test_case = self.GetCrashedTestCase(output) |
| 406 if crashed_test_case: | |
| 407 results.append(base_test_result.BaseTestResult(crashed_test_case, \ | |
|
jbudorick
2016/03/01 05:05:26
nit: again, no \
| |
| 408 base_test_result.ResultType.CRASH)) | |
| 381 return results | 409 return results |
| 382 | 410 |
| 383 #override | 411 #override |
| 384 def TearDown(self): | 412 def TearDown(self): |
| 385 """Clear the mappings created by SetUp.""" | 413 """Clear the mappings created by SetUp.""" |
| 386 if self._isolate_delegate: | 414 if self._isolate_delegate: |
| 387 self._isolate_delegate.Clear() | 415 self._isolate_delegate.Clear() |
| 388 | 416 |
| OLD | NEW |