Index: third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py |
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py |
index 4fa86268206434ea6c30b456a8d778e4e7e74470..1c69745662580df8e926fa24d751ed4212ead5c8 100644 |
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py |
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py |
@@ -25,7 +25,6 @@ |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- |
"""A helper class for reading in and dealing with tests expectations |
for layout tests. |
""" |
@@ -39,13 +38,12 @@ from webkitpy.layout_tests.models.test_configuration import TestConfigurationCon |
_log = logging.getLogger(__name__) |
- |
# Test expectation and specifier constants. |
# |
# FIXME: range() starts with 0 which makes if expectation checks harder |
# as PASS is 0. |
-(PASS, FAIL, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, TIMEOUT, CRASH, LEAK, SKIP, WONTFIX, |
- SLOW, REBASELINE, NEEDS_REBASELINE, NEEDS_MANUAL_REBASELINE, MISSING, FLAKY, NOW, NONE) = range(19) |
+(PASS, FAIL, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, TIMEOUT, CRASH, LEAK, SKIP, WONTFIX, SLOW, REBASELINE, NEEDS_REBASELINE, |
+ NEEDS_MANUAL_REBASELINE, MISSING, FLAKY, NOW, NONE) = range(19) |
# FIXME: Perhas these two routines should be part of the Port instead? |
BASELINE_SUFFIX_LIST = ('png', 'wav', 'txt') |
@@ -90,7 +88,8 @@ class TestExpectationParser(object): |
def __init__(self, port, all_tests, is_lint_mode): |
self._port = port |
- self._test_configuration_converter = TestConfigurationConverter(set(port.all_test_configurations()), port.configuration_specifier_macros()) |
+ self._test_configuration_converter = TestConfigurationConverter( |
+ set(port.all_test_configurations()), port.configuration_specifier_macros()) |
if all_tests: |
self._all_tests = set(all_tests) |
@@ -122,7 +121,6 @@ class TestExpectationParser(object): |
self._parse_line(expectation_line) |
return expectation_line |
- |
def expectation_for_skipped_test(self, test_name): |
if not self._port.test_exists(test_name): |
_log.warning('The following test %s from the Skipped list doesn\'t exist' % test_name) |
@@ -158,7 +156,8 @@ class TestExpectationParser(object): |
self._lint_line(expectation_line) |
parsed_specifiers = set([self._parse_specifier(specifier) for specifier in expectation_line.specifiers]) |
- expectation_line.matching_configurations = self._test_configuration_converter.to_config_set(parsed_specifiers, expectation_line.warnings) |
+ expectation_line.matching_configurations = self._test_configuration_converter.to_config_set(parsed_specifiers, |
+ expectation_line.warnings) |
def _lint_line(self, expectation_line): |
expectations = [expectation.lower() for expectation in expectation_line.expectations] |
@@ -173,7 +172,8 @@ class TestExpectationParser(object): |
expectation_line.warnings.append('A reftest cannot be marked as NeedsRebaseline/NeedsManualRebaseline') |
specifiers = [specifier.lower() for specifier in expectation_line.specifiers] |
- if (self.REBASELINE_MODIFIER in expectations or self.NEEDS_REBASELINE_MODIFIER in expectations) and ('debug' in specifiers or 'release' in specifiers): |
+ if (self.REBASELINE_MODIFIER in expectations or self.NEEDS_REBASELINE_MODIFIER in expectations) and ( |
+ 'debug' in specifiers or 'release' in specifiers): |
expectation_line.warnings.append('A test cannot be rebaselined for Debug/Release.') |
def _parse_expectations(self, expectation_line): |
@@ -217,9 +217,17 @@ class TestExpectationParser(object): |
# FIXME: Update the original specifiers and remove this once the old syntax is gone. |
_configuration_tokens_list = [ |
- 'Mac', 'Mac10.9', 'Mac10.10', 'Mac10.11', 'Retina', |
- 'Win', 'Win7', 'Win10', |
- 'Linux', 'Precise', 'Trusty', |
+ 'Mac', |
+ 'Mac10.9', |
+ 'Mac10.10', |
+ 'Mac10.11', |
+ 'Retina', |
+ 'Win', |
+ 'Win7', |
+ 'Win10', |
+ 'Linux', |
+ 'Precise', |
+ 'Trusty', |
'Android', |
'Release', |
'Debug', |
@@ -244,8 +252,8 @@ class TestExpectationParser(object): |
'WontFix': 'WONTFIX', |
} |
- _inverted_expectation_tokens = dict([(value, name) for name, value in _expectation_tokens.iteritems()] + |
- [('TEXT', 'Failure'), ('IMAGE', 'Failure'), ('IMAGE+TEXT', 'Failure'), ('AUDIO', 'Failure')]) |
+ _inverted_expectation_tokens = dict([(value, name) for name, value in _expectation_tokens.iteritems()] + [('TEXT', 'Failure'), ( |
+ 'IMAGE', 'Failure'), ('IMAGE+TEXT', 'Failure'), ('AUDIO', 'Failure')]) |
# FIXME: Seems like these should be classmethods on TestExpectationLine instead of TestExpectationParser. |
@classmethod |
@@ -289,10 +297,8 @@ class TestExpectationParser(object): |
tokens = remaining_string.split() |
state = 'start' |
for token in tokens: |
- if (token.startswith(WEBKIT_BUG_PREFIX) or |
- token.startswith(CHROMIUM_BUG_PREFIX) or |
- token.startswith(V8_BUG_PREFIX) or |
- token.startswith(NAMED_BUG_PREFIX)): |
+ if (token.startswith(WEBKIT_BUG_PREFIX) or token.startswith(CHROMIUM_BUG_PREFIX) or token.startswith(V8_BUG_PREFIX) or |
+ token.startswith(NAMED_BUG_PREFIX)): |
if state != 'start': |
warnings.append('"%s" is not at the start of the line.' % token) |
break |
@@ -359,7 +365,8 @@ class TestExpectationParser(object): |
warnings.append('SLOW tests should ony be added to SlowTests and not to TestExpectations.') |
if 'WONTFIX' in expectations and ('NeverFixTests' not in filename and 'StaleTestExpectations' not in filename): |
- warnings.append('WONTFIX tests should ony be added to NeverFixTests or StaleTestExpectations and not to TestExpectations.') |
+ warnings.append( |
+ 'WONTFIX tests should ony be added to NeverFixTests or StaleTestExpectations and not to TestExpectations.') |
if 'NeverFixTests' in filename and expectations != ['WONTFIX', 'SKIP']: |
warnings.append('Only WONTFIX expectations are allowed in NeverFixTests') |
@@ -405,24 +412,18 @@ class TestExpectationLine(object): |
self.is_skipped_outside_expectations_file = False |
def __str__(self): |
- return "TestExpectationLine{name=%s, matching_configurations=%s, original_string=%s}" % (self.name, self.matching_configurations, self.original_string) |
+ return "TestExpectationLine{name=%s, matching_configurations=%s, original_string=%s}" % ( |
+ self.name, self.matching_configurations, self.original_string) |
def __eq__(self, other): |
- return (self.original_string == other.original_string |
- and self.filename == other.filename |
- and self.line_numbers == other.line_numbers |
- and self.name == other.name |
- and self.path == other.path |
- and self.bugs == other.bugs |
- and self.specifiers == other.specifiers |
- and self.parsed_specifiers == other.parsed_specifiers |
- and self.matching_configurations == other.matching_configurations |
- and self.expectations == other.expectations |
- and self.parsed_expectations == other.parsed_expectations |
- and self.comment == other.comment |
- and self.matching_tests == other.matching_tests |
- and self.warnings == other.warnings |
- and self.is_skipped_outside_expectations_file == other.is_skipped_outside_expectations_file) |
+ return (self.original_string == other.original_string and self.filename == other.filename and |
+ self.line_numbers == other.line_numbers and self.name == other.name and self.path == other.path and |
+ self.bugs == other.bugs and self.specifiers == other.specifiers and |
+ self.parsed_specifiers == other.parsed_specifiers and |
+ self.matching_configurations == other.matching_configurations and self.expectations == other.expectations and |
+ self.parsed_expectations == other.parsed_expectations and self.comment == other.comment and |
+ self.matching_tests == other.matching_tests and self.warnings == other.warnings and |
+ self.is_skipped_outside_expectations_file == other.is_skipped_outside_expectations_file) |
def is_invalid(self): |
return bool(self.warnings and self.warnings != [TestExpectationParser.MISSING_BUG_WARNING]) |
@@ -474,7 +475,8 @@ class TestExpectationLine(object): |
return result |
def to_string(self, test_configuration_converter, include_specifiers=True, include_expectations=True, include_comment=True): |
- parsed_expectation_to_string = dict([[parsed_expectation, expectation_string] for expectation_string, parsed_expectation in TestExpectations.EXPECTATIONS.items()]) |
+ parsed_expectation_to_string = dict([[parsed_expectation, expectation_string] |
+ for expectation_string, parsed_expectation in TestExpectations.EXPECTATIONS.items()]) |
if self.is_invalid(): |
return self.original_string or '' |
@@ -492,8 +494,8 @@ class TestExpectationLine(object): |
result.append(self._format_line(self.bugs, specifiers, self.name, expectations, self.comment)) |
return "\n".join(result) if result else None |
- return self._format_line(self.bugs, self.specifiers, self.name, self.expectations, self.comment, |
- include_specifiers, include_expectations, include_comment) |
+ return self._format_line(self.bugs, self.specifiers, self.name, self.expectations, self.comment, include_specifiers, |
+ include_expectations, include_comment) |
def to_csv(self): |
# Note that this doesn't include the comments. |
@@ -521,7 +523,14 @@ class TestExpectationLine(object): |
return expectations |
@staticmethod |
- def _format_line(bugs, specifiers, name, expectations, comment, include_specifiers=True, include_expectations=True, include_comment=True): |
+ def _format_line(bugs, |
+ specifiers, |
+ name, |
+ expectations, |
+ comment, |
+ include_specifiers=True, |
+ include_expectations=True, |
+ include_comment=True): |
new_specifiers = [] |
new_expectations = [] |
for specifier in specifiers: |
@@ -595,7 +604,9 @@ class TestExpectationsModel(object): |
if other_line not in merge_lines_cache[self_line]: |
merge_lines_cache[self_line][other_line] = TestExpectationLine.merge_expectation_lines( |
- self_line, other_line, model_all_expectations=False) |
+ self_line, |
+ other_line, |
+ model_all_expectations=False) |
merged_line = merge_lines_cache[self_line][other_line] |
else: |
@@ -678,8 +689,7 @@ class TestExpectationsModel(object): |
self._clear_expectations_for_test(test) |
del self._test_to_expectation_line[test] |
- def add_expectation_line(self, expectation_line, |
- model_all_expectations=False): |
+ def add_expectation_line(self, expectation_line, model_all_expectations=False): |
"""Returns a list of warnings encountered while matching specifiers.""" |
if expectation_line.is_invalid(): |
@@ -690,7 +700,8 @@ class TestExpectationsModel(object): |
continue |
if model_all_expectations: |
- expectation_line = TestExpectationLine.merge_expectation_lines(self.get_expectation_line(test), expectation_line, model_all_expectations) |
+ expectation_line = TestExpectationLine.merge_expectation_lines( |
+ self.get_expectation_line(test), expectation_line, model_all_expectations) |
self._clear_expectations_for_test(test) |
self._test_to_expectation_line[test] = expectation_line |
@@ -780,28 +791,32 @@ class TestExpectationsModel(object): |
# to be warnings and return False". |
if prev_expectation_line.matching_configurations == expectation_line.matching_configurations: |
- expectation_line.warnings.append('Duplicate or ambiguous entry lines %s:%s and %s:%s.' % ( |
- self._shorten_filename(prev_expectation_line.filename), prev_expectation_line.line_numbers, |
- self._shorten_filename(expectation_line.filename), expectation_line.line_numbers)) |
+ expectation_line.warnings.append('Duplicate or ambiguous entry lines %s:%s and %s:%s.' % |
+ (self._shorten_filename(prev_expectation_line.filename), |
+ prev_expectation_line.line_numbers, self._shorten_filename(expectation_line.filename), |
+ expectation_line.line_numbers)) |
return True |
if prev_expectation_line.matching_configurations >= expectation_line.matching_configurations: |
- expectation_line.warnings.append('More specific entry for %s on line %s:%s overrides line %s:%s.' % (expectation_line.name, |
- self._shorten_filename(prev_expectation_line.filename), prev_expectation_line.line_numbers, |
- self._shorten_filename(expectation_line.filename), expectation_line.line_numbers)) |
+ expectation_line.warnings.append('More specific entry for %s on line %s:%s overrides line %s:%s.' % |
+ (expectation_line.name, self._shorten_filename(prev_expectation_line.filename), |
+ prev_expectation_line.line_numbers, self._shorten_filename(expectation_line.filename), |
+ expectation_line.line_numbers)) |
# FIXME: return False if we want more specific to win. |
return True |
if prev_expectation_line.matching_configurations <= expectation_line.matching_configurations: |
- expectation_line.warnings.append('More specific entry for %s on line %s:%s overrides line %s:%s.' % (expectation_line.name, |
- self._shorten_filename(expectation_line.filename), expectation_line.line_numbers, |
- self._shorten_filename(prev_expectation_line.filename), prev_expectation_line.line_numbers)) |
+ expectation_line.warnings.append('More specific entry for %s on line %s:%s overrides line %s:%s.' % |
+ (expectation_line.name, self._shorten_filename(expectation_line.filename), |
+ expectation_line.line_numbers, self._shorten_filename(prev_expectation_line.filename), |
+ prev_expectation_line.line_numbers)) |
return True |
if prev_expectation_line.matching_configurations & expectation_line.matching_configurations: |
- expectation_line.warnings.append('Entries for %s on lines %s:%s and %s:%s match overlapping sets of configurations.' % (expectation_line.name, |
- self._shorten_filename(prev_expectation_line.filename), prev_expectation_line.line_numbers, |
- self._shorten_filename(expectation_line.filename), expectation_line.line_numbers)) |
+ expectation_line.warnings.append('Entries for %s on lines %s:%s and %s:%s match overlapping sets of configurations.' % |
+ (expectation_line.name, self._shorten_filename(prev_expectation_line.filename), |
+ prev_expectation_line.line_numbers, self._shorten_filename(expectation_line.filename), |
+ expectation_line.line_numbers)) |
return True |
# Configuration sets are disjoint, then. |
@@ -853,8 +868,7 @@ class TestExpectations(object): |
TestExpectationParser.NEEDS_MANUAL_REBASELINE_MODIFIER: NEEDS_MANUAL_REBASELINE, |
TestExpectationParser.WONTFIX_MODIFIER: WONTFIX, |
TestExpectationParser.SLOW_MODIFIER: SLOW, |
- TestExpectationParser.REBASELINE_MODIFIER: REBASELINE, |
- } |
+ TestExpectationParser.REBASELINE_MODIFIER: REBASELINE, } |
EXPECTATIONS_TO_STRING = dict((k, v) for (v, k) in EXPECTATIONS.iteritems()) |
@@ -875,17 +889,13 @@ class TestExpectations(object): |
BUILD_TYPES = ('debug', 'release') |
- TIMELINES = {TestExpectationParser.WONTFIX_MODIFIER: WONTFIX, |
- 'now': NOW} |
+ TIMELINES = {TestExpectationParser.WONTFIX_MODIFIER: WONTFIX, 'now': NOW} |
- RESULT_TYPES = {'skip': SKIP, |
- 'pass': PASS, |
- 'fail': FAIL, |
- 'flaky': FLAKY} |
+ RESULT_TYPES = {'skip': SKIP, 'pass': PASS, 'fail': FAIL, 'flaky': FLAKY} |
@classmethod |
def expectation_from_string(cls, string): |
- assert(' ' not in string) # This only handles one expectation at a time. |
+ assert (' ' not in string) # This only handles one expectation at a time. |
return cls.EXPECTATIONS.get(string.lower()) |
@staticmethod |
@@ -900,7 +910,8 @@ class TestExpectations(object): |
if result in expected_results: |
return True |
- if result in (PASS, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, MISSING) and (NEEDS_REBASELINE in expected_results or NEEDS_MANUAL_REBASELINE in expected_results): |
+ if result in (PASS, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, MISSING) and (NEEDS_REBASELINE in expected_results or |
+ NEEDS_MANUAL_REBASELINE in expected_results): |
return True |
if result in (TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO) and (FAIL in expected_results): |
return True |
@@ -966,7 +977,13 @@ class TestExpectations(object): |
# FIXME: This constructor does too much work. We should move the actual parsing of |
# the expectations into separate routines so that linting and handling overrides |
# can be controlled separately, and the constructor can be more of a no-op. |
- def __init__(self, port, tests=None, include_overrides=True, expectations_dict=None, model_all_expectations=False, is_lint_mode=False): |
+ def __init__(self, |
+ port, |
+ tests=None, |
+ include_overrides=True, |
+ expectations_dict=None, |
+ model_all_expectations=False, |
+ is_lint_mode=False): |
self._full_test_list = tests |
self._test_config = port.test_configuration() |
self._is_lint_mode = is_lint_mode |
@@ -1057,8 +1074,8 @@ class TestExpectations(object): |
warnings = [] |
for expectation in self._expectations: |
for warning in expectation.warnings: |
- warnings.append('%s:%s %s %s' % (self._shorten_filename(expectation.filename), expectation.line_numbers, |
- warning, expectation.name if expectation.expectations else expectation.original_string)) |
+ warnings.append('%s:%s %s %s' % (self._shorten_filename(expectation.filename), expectation.line_numbers, warning, |
+ expectation.name if expectation.expectations else expectation.original_string)) |
if warnings: |
self._has_warnings = True |