summaryrefslogtreecommitdiff
path: root/chromium/media/tools/layout_tests/test_expectations.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/tools/layout_tests/test_expectations.py')
-rw-r--r--chromium/media/tools/layout_tests/test_expectations.py123
1 files changed, 123 insertions, 0 deletions
diff --git a/chromium/media/tools/layout_tests/test_expectations.py b/chromium/media/tools/layout_tests/test_expectations.py
new file mode 100644
index 00000000000..58b21de6883
--- /dev/null
+++ b/chromium/media/tools/layout_tests/test_expectations.py
@@ -0,0 +1,123 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A module to analyze test expectations for Webkit layout tests."""
+
+import urllib2
+
+from webkitpy.layout_tests.models.test_expectations import *
+
+# Default location for chromium test expectation file.
+# TODO(imasaki): support multiple test expectations files.
+DEFAULT_TEST_EXPECTATIONS_LOCATION = (
+ 'http://src.chromium.org/blink/trunk/LayoutTests/TestExpectations')
+
+# The following is from test expectation syntax. The detail can be found in
+# http://www.chromium.org/developers/testing/webkit-layout-tests#TOC-Test-Expectations
+# <decision> ::== [SKIP] [WONTFIX] [SLOW]
+DECISION_NAMES = ['SKIP', 'WONTFIX', 'SLOW']
+# <config> ::== RELEASE | DEBUG
+CONFIG_NAMES = ['RELEASE', 'DEBUG']
+# Only hard code keywords we don't expect to change. Determine the rest from
+# the format of the status line.
+KNOWN_TE_KEYWORDS = DECISION_NAMES + CONFIG_NAMES
+
+
+class TestExpectations(object):
+ """A class to model the content of test expectation file for analysis.
+
+ This class retrieves the TestExpectations file via HTTP from WebKit and uses
+ the WebKit layout test processor to process each line.
+
+ The resulting dictionary is stored in |all_test_expectation_info| and looks
+ like:
+
+ {'<test name>': [{'<modifier0>': True, '<modifier1>': True, ...,
+ 'Platforms: ['<platform0>', ... ], 'Bugs': ['....']}]}
+
+ Duplicate keys are merged (though technically they shouldn't exist).
+
+ Example:
+ crbug.com/145590 [ Android ] \
+ platform/chromium/media/video-frame-size-change.html [ Timeout ]
+ webkit.org/b/84724 [ SnowLeopard ] \
+ platform/chromium/media/video-frame-size-change.html \
+ [ ImageOnlyFailure Pass ]
+
+ {'platform/chromium/media/video-frame-size-change.html': [{'IMAGE': True,
+ 'Bugs': ['BUGWK84724', 'BUGCR145590'], 'Comments': '',
+ 'Platforms': ['SNOWLEOPARD', 'ANDROID'], 'TIMEOUT': True, 'PASS': True}]}
+ """
+
+ def __init__(self, url=DEFAULT_TEST_EXPECTATIONS_LOCATION):
+ """Read the test expectation file from the specified URL and parse it.
+
+ Args:
+ url: A URL string for the test expectation file.
+
+ Raises:
+ NameError when the test expectation file cannot be retrieved from |url|.
+ """
+ self.all_test_expectation_info = {}
+ resp = urllib2.urlopen(url)
+ if resp.code != 200:
+ raise NameError('Test expectation file does not exist in %s' % url)
+ # Start parsing each line.
+ for line in resp.read().split('\n'):
+ line = line.strip()
+ # Skip comments.
+ if line.startswith('#'):
+ continue
+ testname, te_info = self.ParseLine(line)
+ if not testname or not te_info:
+ continue
+ if testname in self.all_test_expectation_info:
+ # Merge keys if entry already exists.
+ for k in te_info.keys():
+ if (isinstance(te_info[k], list) and
+ k in self.all_test_expectation_info[testname]):
+ self.all_test_expectation_info[testname][0][k] += te_info[k]
+ else:
+ self.all_test_expectation_info[testname][0][k] = te_info[k]
+ else:
+ self.all_test_expectation_info[testname] = [te_info]
+
+ @staticmethod
+ def ParseLine(line):
+ """Parses the provided line using WebKit's TextExpecations parser.
+
+ Returns:
+ Tuple of test name, test expectations dictionary. See class documentation
+ for the format of the dictionary
+ """
+ test_expectation_info = {}
+ parsed = TestExpectationParser._tokenize_line('TestExpectations', line, 0)
+ if parsed.is_invalid():
+ return None, None
+
+ test_expectation_info['Comments'] = parsed.comment or ''
+
+ # Split the modifiers dictionary into the format we want.
+ remaining_modifiers = list(parsed.modifiers)
+ test_expectation_info['Bugs'] = []
+ for m in parsed.modifiers:
+ if (m.startswith(WEBKIT_BUG_PREFIX) or
+ m.startswith(CHROMIUM_BUG_PREFIX) or
+ m.startswith(V8_BUG_PREFIX) or
+ m.startswith(NAMED_BUG_PREFIX)):
+ test_expectation_info['Bugs'].append(m)
+ remaining_modifiers.remove(m)
+ elif m in KNOWN_TE_KEYWORDS:
+ test_expectation_info[m] = True
+ remaining_modifiers.remove(m)
+
+ # The modifiers left over should all be platform names.
+ test_expectation_info['Platforms'] = list(remaining_modifiers)
+
+ # Shovel the expectations and modifiers in as "<key>: True" entries. Ugly,
+ # but required by the rest of the pipeline for parsing.
+ for m in parsed.expectations + remaining_modifiers:
+ test_expectation_info[m] = True
+
+ return parsed.name, test_expectation_info