Changeset 86020 in webkit


Ignore:
Timestamp:
May 7, 2011 7:50:09 PM (13 years ago)
Author:
abarth@webkit.org
Message:

2011-05-07 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

Testing EWS spins on patches with a large number of failures
https://bugs.webkit.org/show_bug.cgi?id=60441

In cases where the tree has a small number of persistent failures but a
patch has a large number of failures, we weren't believing any results.
That lead to us retrying the patch forever while we waited for
trustworthy results that would never come.

This patch loosens the semantics of unexpected_failures to return a
subset (rather than the exact set) of unexpected failures. In the case
where the tree has a bounded number of failures and the patch has an
unbounded number of failures, we can accurately compute such a subset
and reject the patch.

  • Scripts/webkitpy/tool/bot/expectedfailures.py:
  • Scripts/webkitpy/tool/bot/expectedfailures_unittest.py:
  • Scripts/webkitpy/tool/bot/patchanalysistask.py:
  • Scripts/webkitpy/tool/commands/earlywarningsystem.py:
  • Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py:
Location:
trunk/Tools
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r86013 r86020  
     12011-05-07  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Testing EWS spins on patches with a large number of failures
     6        https://bugs.webkit.org/show_bug.cgi?id=60441
     7
     8        In cases where the tree has a small number of persistent failures but a
     9        patch has a large number of failures, we weren't believing any results.
     10        That lead to us retrying the patch forever while we waited for
     11        trustworthy results that would never come.
     12
     13        This patch loosens the semantics of unexpected_failures to return a
     14        subset (rather than the exact set) of unexpected failures.  In the case
     15        where the tree has a bounded number of failures and the patch has an
     16        unbounded number of failures, we can accurately compute such a subset
     17        and reject the patch.
     18
     19        * Scripts/webkitpy/tool/bot/expectedfailures.py:
     20        * Scripts/webkitpy/tool/bot/expectedfailures_unittest.py:
     21        * Scripts/webkitpy/tool/bot/patchanalysistask.py:
     22        * Scripts/webkitpy/tool/commands/earlywarningsystem.py:
     23        * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py:
     24
    1252011-05-07  Joe Mason  <jmason@rim.com>
    226
  • trunk/Tools/Scripts/webkitpy/tool/bot/expectedfailures.py

    r85463 r86020  
    3131    def __init__(self):
    3232        self._failures = set()
     33        # If the set of failures is unbounded, self._failures isn't very
     34        # meaningful because we can't store an unbounded set in memory.
     35        self._failures_are_bounded = True
     36
     37    def _has_failures(self, results):
     38        return bool(results and len(results.failing_tests()) != 0)
     39
     40    def has_bounded_failures(self, results):
     41        assert(results)  # You probably want to call _has_failures first!
     42        return bool(results.failure_limit_count() and len(results.failing_tests()) < results.failure_limit_count())
    3343
    3444    def _can_trust_results(self, results):
    35         if not results or not results.failure_limit_count():
    36             return False
    37         return len(results.failing_tests()) != 0 and len(results.failing_tests()) < results.failure_limit_count()
     45        return self._has_failures(results) and self.has_bounded_failures(results)
    3846
    3947    def failures_were_expected(self, results):
     
    4250        return set(results.failing_tests()) <= self._failures
    4351
    44     def unexpected_failures(self, results):
    45         if not self._can_trust_results(results):
     52    def unexpected_failures_observed(self, results):
     53        if not self._has_failures(results):
     54            return None
     55        if not self._failures_are_bounded:
    4656            return None
    4757        return set(results.failing_tests()) - self._failures
     
    5060        if run_success:
    5161            self._failures = set()
     62            self._failures_are_bounded = True
    5263        elif self._can_trust_results(results):
    5364            # Remove all expected failures which are not in the new failing results.
    5465            self._failures.intersection_update(set(results.failing_tests()))
     66            self._failures_are_bounded = True
    5567
    5668    def grow_expected_failures(self, results):
    5769        if not self._can_trust_results(results):
     70            self._failures_are_bounded = False
    5871            return
    5972        self._failures.update(results.failing_tests())
     73        self._failures_are_bounded = True
    6074        # FIXME: Should we assert() here that expected_failures never crosses a certain size?
  • trunk/Tools/Scripts/webkitpy/tool/bot/expectedfailures_unittest.py

    r85463 r86020  
    7474        self._assert_expected(failures, ['baz.html'], False)
    7575
    76     def test_unexpected_failures(self):
     76    def test_unexpected_failures_observed(self):
    7777        failures = ExpectedFailures()
    7878        failures.grow_expected_failures(MockResults(['foo.html']))
    79         self.assertEquals(failures.unexpected_failures(MockResults(['foo.html', 'bar.html'])), set(['bar.html']))
    80         self.assertEquals(failures.unexpected_failures(MockResults(['baz.html'])), set(['baz.html']))
     79        self.assertEquals(failures.unexpected_failures_observed(MockResults(['foo.html', 'bar.html'])), set(['bar.html']))
     80        self.assertEquals(failures.unexpected_failures_observed(MockResults(['baz.html'])), set(['baz.html']))
     81        unbounded_results = MockResults(['baz.html', 'qux.html', 'taco.html'], failure_limit=3)
     82        self.assertEquals(failures.unexpected_failures_observed(unbounded_results), set(['baz.html', 'qux.html', 'taco.html']))
     83        unbounded_results_with_existing_failure = MockResults(['foo.html', 'baz.html', 'qux.html', 'taco.html'], failure_limit=4)
     84        self.assertEquals(failures.unexpected_failures_observed(unbounded_results_with_existing_failure), set(['baz.html', 'qux.html', 'taco.html']))
     85
     86    def test_unexpected_failures_observed_when_tree_is_hosed(self):
     87        failures = ExpectedFailures()
     88        failures.grow_expected_failures(MockResults(['foo.html', 'banana.html'], failure_limit=2))
     89        self.assertEquals(failures.unexpected_failures_observed(MockResults(['foo.html', 'bar.html'])), None)
     90        self.assertEquals(failures.unexpected_failures_observed(MockResults(['baz.html'])), None)
     91        unbounded_results = MockResults(['baz.html', 'qux.html', 'taco.html'], failure_limit=3)
     92        self.assertEquals(failures.unexpected_failures_observed(unbounded_results), None)
     93        unbounded_results_with_existing_failure = MockResults(['foo.html', 'baz.html', 'qux.html', 'taco.html'], failure_limit=4)
     94        self.assertEquals(failures.unexpected_failures_observed(unbounded_results_with_existing_failure), None)
  • trunk/Tools/Scripts/webkitpy/tool/bot/patchanalysistask.py

    r85509 r86020  
    221221        # Now that we have updated information about failing tests with a clean checkout, we can
    222222        # tell if our original failures were unexpected and fail the patch if necessary.
    223         if self._expected_failures.unexpected_failures(first_results):
     223        if self._expected_failures.unexpected_failures_observed(first_results):
    224224            return self.report_failure(first_results_archive, first_results)
    225225
  • trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py

    r85922 r86020  
    131131    def _failing_tests_message(self, task, patch):
    132132        results = task.results_from_patch_test_run(patch)
    133         unexpected_failures = self._expected_failures.unexpected_failures(results)
     133        unexpected_failures = self._expected_failures.unexpected_failures_observed(results)
    134134        if not unexpected_failures:
    135135            return None
  • trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py

    r85922 r86020  
    9292        ews._options = MockOptions(port=None, confirm=False)
    9393        OutputCapture().assert_outputs(self, ews.begin_work_queue, expected_stderr=self._default_begin_work_queue_stderr(ews.name, ews._tool.scm().checkout_root))
    94         ews._expected_failures.unexpected_failures = lambda results: set(["foo.html", "bar.html"])
     94        ews._expected_failures.unexpected_failures_observed = lambda results: set(["foo.html", "bar.html"])
    9595        task = Mock()
    9696        patch = ews._tool.bugs.fetch_attachment(197)
Note: See TracChangeset for help on using the changeset viewer.