summaryrefslogtreecommitdiffstats
path: root/Tools/Scripts/webkitpy/common/net/layouttestresults.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Scripts/webkitpy/common/net/layouttestresults.py')
-rw-r--r--Tools/Scripts/webkitpy/common/net/layouttestresults.py101
1 files changed, 79 insertions, 22 deletions
diff --git a/Tools/Scripts/webkitpy/common/net/layouttestresults.py b/Tools/Scripts/webkitpy/common/net/layouttestresults.py
index 15e95ce..28caad4 100644
--- a/Tools/Scripts/webkitpy/common/net/layouttestresults.py
+++ b/Tools/Scripts/webkitpy/common/net/layouttestresults.py
@@ -27,8 +27,12 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# A module for parsing results.html files generated by old-run-webkit-tests
+# This class is one big hack and only needs to exist until we transition to new-run-webkit-tests.
+from webkitpy.common.system.deprecated_logging import log
from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup, SoupStrainer
+from webkitpy.layout_tests.layout_package import test_results
+from webkitpy.layout_tests.layout_package import test_failures
# FIXME: This should be unified with all the layout test results code in the layout_tests package
@@ -57,36 +61,89 @@ class LayoutTestResults(object):
]
@classmethod
+ def _failures_from_fail_row(self, row):
+ # Look at all anchors in this row, and guess what type
+ # of new-run-webkit-test failures they equate to.
+ failures = set()
+ test_name = None
+ for anchor in row.findAll("a"):
+ anchor_text = unicode(anchor.string)
+ if not test_name:
+ test_name = anchor_text
+ continue
+ if anchor_text in ["expected image", "image diffs"] or '%' in anchor_text:
+ failures.add(test_failures.FailureImageHashMismatch())
+ elif anchor_text in ["expected", "actual", "diff", "pretty diff"]:
+ failures.add(test_failures.FailureTextMismatch())
+ else:
+ log("Unhandled link text in results.html parsing: %s. Please file a bug against webkitpy." % anchor_text)
+ # FIXME: Its possible the row contained no links due to ORWT brokeness.
+ # We should probably assume some type of failure anyway.
+ return failures
+
+ @classmethod
+ def _failures_from_row(cls, row, table_title):
+ if table_title == cls.fail_key:
+ return cls._failures_from_fail_row(row)
+ if table_title == cls.crash_key:
+ return [test_failures.FailureCrash()]
+ if table_title == cls.timeout_key:
+ return [test_failures.FailureTimeout()]
+ if table_title == cls.missing_key:
+ return [test_failures.FailureMissingResult(), test_failures.FailureMissingImageHash(), test_failures.FailureMissingImage()]
+ return None
+
+ @classmethod
+ def _test_result_from_row(cls, row, table_title):
+ test_name = unicode(row.find("a").string)
+ failures = cls._failures_from_row(row, table_title)
+ # TestResult is a class designed to work with new-run-webkit-tests.
+ # old-run-webkit-tests does not save quite enough information in results.html for us to parse.
+ # FIXME: It's unclear if test_name should include LayoutTests or not.
+ return test_results.TestResult(test_name, failures)
+
+ @classmethod
+ def _parse_results_table(cls, table):
+ table_title = unicode(table.findPreviousSibling("p").string)
+ if table_title not in cls.expected_keys:
+ # This Exception should only ever be hit if run-webkit-tests changes its results.html format.
+ raise Exception("Unhandled title: %s" % table_title)
+ # Ignore stderr failures. Everyone ignores them anyway.
+ if table_title == cls.stderr_key:
+ return []
+ # FIXME: We might end with two TestResults object for the same test if it appears in more than one row.
+ return [cls._test_result_from_row(row, table_title) for row in table.findAll("tr")]
+
+ @classmethod
def _parse_results_html(cls, page):
- if not page:
- return None
- parsed_results = {}
tables = BeautifulSoup(page).findAll("table")
- for table in tables:
- table_title = unicode(table.findPreviousSibling("p").string)
- if table_title not in cls.expected_keys:
- # This Exception should only ever be hit if run-webkit-tests changes its results.html format.
- raise Exception("Unhandled title: %s" % table_title)
- # We might want to translate table titles into identifiers before storing.
- parsed_results[table_title] = [unicode(row.find("a").string) for row in table.findAll("tr")]
-
- return parsed_results
+ return sum([cls._parse_results_table(table) for table in tables], [])
@classmethod
def results_from_string(cls, string):
- parsed_results = cls._parse_results_html(string)
- if not parsed_results:
+ if not string:
return None
- return cls(parsed_results)
+ test_results = cls._parse_results_html(string)
+ if not test_results:
+ return None
+ return cls(test_results)
+
+ def __init__(self, test_results):
+ self._test_results = test_results
+
+ def test_results(self):
+ return self._test_results
- def __init__(self, parsed_results):
- self._parsed_results = parsed_results
+ def results_matching_failure_types(self, failure_types):
+ return [result for result in self._test_results if result.has_failure_matching_types(failure_types)]
- def parsed_results(self):
- return self._parsed_results
+ def tests_matching_failure_types(self, failure_types):
+ return [result.filename for result in self.results_matching_failure_types(failure_types)]
- def results_matching_keys(self, result_keys):
- return sorted(sum([tests for key, tests in self._parsed_results.items() if key in result_keys], []))
+ def failing_test_results(self):
+ # These should match the "fail", "crash", and "timeout" keys.
+ failure_types = [test_failures.FailureTextMismatch, test_failures.FailureImageHashMismatch, test_failures.FailureCrash, test_failures.FailureTimeout]
+ return self.results_matching_failure_types(failure_types)
def failing_tests(self):
- return self.results_matching_keys([self.fail_key, self.crash_key, self.timeout_key])
+ return [result.filename for result in self.failing_test_results()]