Chromium Code Reviews| 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(): |