Index: scripts/common/gtest_utils.py |
diff --git a/scripts/common/gtest_utils.py b/scripts/common/gtest_utils.py |
index 0e1c17059687f8a903036f6d14227de7e0973144..b9e32bd149d23c7935eff3bf4933b0ed94ca4e7a 100755 |
--- a/scripts/common/gtest_utils.py |
+++ b/scripts/common/gtest_utils.py |
@@ -3,6 +3,7 @@ |
# Use of this source code is governed by a BSD-style license that can be |
# found in the LICENSE file. |
+from common import chromium_utils |
import json |
import os |
import re |
@@ -419,6 +420,7 @@ class GTestJSONParser(object): |
self.failed_tests = set() |
self.flaky_tests = set() |
self.test_logs = {} |
+ self.ignored_failed_tests = set() |
self.parsing_errors = [] |
@@ -433,11 +435,14 @@ class GTestJSONParser(object): |
return sorted(self.passed_tests) |
def FailedTests(self, include_fails=False, include_flaky=False): |
- return sorted(self.failed_tests) |
+ return sorted(self.failed_tests - self.ignored_failed_tests) |
def FailureDescription(self, test): |
return self.test_logs.get(test, []) |
+ def IgnoredFailedTests(self): |
+ return sorted(self.ignored_failed_tests) |
+ |
@staticmethod |
def SuppressionHashes(): |
return [] |
@@ -470,7 +475,7 @@ class GTestJSONParser(object): |
self.delete_json_file = True |
return self.json_file_path |
- def ProcessJSONFile(self): |
+ def ProcessJSONFile(self, build_dir): |
if not self.json_file_path: |
return |
@@ -484,14 +489,97 @@ class GTestJSONParser(object): |
if json_output: |
self.parsing_errors = json_output.split('\n') |
else: |
- self.ProcessJSONData(json_data) |
+ self.ProcessJSONData(json_data, build_dir) |
if self.delete_json_file: |
os.remove(self.json_file_path) |
- def ProcessJSONData(self, json_data): |
+ @staticmethod |
+ def ParseIngoredFailedTestSpec(dir_in_chrome): |
ghost stip (do not use)
2014/07/19 01:09:06
ParseIgnored
Sergiy Byelozyorov
2014/07/21 12:39:57
Done.
|
+ """Returns parsed ignored failed test spec. |
+ |
+ Args: |
+ dir_in_chrome: Any directory within chrome checkout to be used as a |
+ reference to find ignored failed test spec file. |
+ |
+ Returns: |
+ A list of tuples (test_name, platforms), where platforms is a list of sets |
+ of platform flags. For example: |
+ |
+ [('MyTest.TestOne', [set('OS_WIN', 'CPU_32_BITS', 'MODE_RELEASE'), |
+ set('OS_LINUX', 'CPU_64_BITS', 'MODE_DEBUG')]), |
+ ('MyTest.TestTwo', [set('OS_MACOSX', 'CPU_64_BITS', 'MODE_RELEASE'), |
+ set('CPU_32_BITS')]), |
+ ('MyTest.TestThree', [set()]] |
+ """ |
+ |
+ try: |
+ ignored_failed_tests_path = chromium_utils.FindUpward( |
+ os.path.abspath(dir_in_chrome), 'tools', 'ignorer_bot', |
+ 'ignored_failed_tests.txt') |
+ except chromium_utils.PathNotFound: |
+ return |
+ |
+ with open(ignored_failed_tests_path) as ignored_failed_tests_file: |
+ ignored_failed_tests_spec = ignored_failed_tests_file.readlines() |
+ |
+ parsed_spec = [] |
+ for spec_line in ignored_failed_tests_spec: |
+ spec_line = spec_line.strip() |
+ if spec_line.startswith('#') or not spec_line: |
+ continue |
+ |
+ # Any number of platform flags identifiers separated by whitespace. |
+ platform_spec_regexp = r'[A-Za-z0-9_\s]*' |
+ |
+ match = re.match( |
+ r'^crbug.com/\d+' # Issue URL. |
ghost stip (do not use)
2014/07/19 01:09:06
my general experience of maintaining regex-based p
Sergiy Byelozyorov
2014/07/21 12:39:57
I will. But in the next version. For now we need s
|
+ r'\s+' # Some whitespace. |
+ r'\[(' + # Opening square bracket '['. |
+ platform_spec_regexp + # At least one platform, and... |
+ r'(?:,' + # ...separated by commas... |
+ platform_spec_regexp + # ...any number of additional... |
+ r')*' # ...platforms. |
+ r')\]' # Closing square bracket ']'. |
+ r'\s+' # Some whitespace. |
+ r'(\S+)$', spec_line) # Test name. |
+ |
+ if not match: |
+ continue |
+ |
+ platform_specs = match.group(1).strip() |
+ test_name = match.group(2).strip() |
+ |
+ platforms = [set(platform.split()) |
+ for platform in platform_specs.split(',')] |
+ |
+ parsed_spec.append((test_name, platforms)) |
+ |
+ return parsed_spec |
+ |
+ |
+ def _RetrieveIgnoredFailuresForPlatform(self, build_dir, platform_flags): |
+ """Parses the ignored failed tests spec into self.ignored_failed_tests.""" |
+ if not build_dir: |
+ return |
+ |
+ platform_flags = set(platform_flags) |
+ parsed_spec = self.ParseIngoredFailedTestSpec(build_dir) |
ghost stip (do not use)
2014/07/19 01:09:06
ParseIgnored
Sergiy Byelozyorov
2014/07/21 12:39:57
Done.
|
+ |
+ if not parsed_spec: |
+ return |
+ |
+ for test_name, platforms in parsed_spec: |
+ for required_platform_flags in platforms: |
+ if required_platform_flags.issubset(platform_flags): |
+ self.ignored_failed_tests.add(test_name) |
+ break |
+ |
+ def ProcessJSONData(self, json_data, build_dir=None): |
# TODO(phajdan.jr): Require disabled_tests to be present (May 2014). |
self.disabled_tests.update(json_data.get('disabled_tests', [])) |
+ self._RetrieveIgnoredFailuresForPlatform(build_dir, |
+ json_data.get('global_tags', [])) |
for iteration_data in json_data['per_iteration_data']: |
for test_name, test_runs in iteration_data.iteritems(): |