Changeset 94540 in webkit


Ignore:
Timestamp:
Sep 5, 2011 4:18:00 PM (13 years ago)
Author:
abarth@webkit.org
Message:

Add a tab to garden-o-matic for viewing expected failures
https://bugs.webkit.org/show_bug.cgi?id=67619

Reviewed by Dimitri Glazkov.

This patch adds a basic tab to garden-o-matic that shows all the tests
failing on the bots, including the expected failures. This patch
mostly involves refactoring existing classes to allow new subclasses.

This view is useful for when gardeners mark tests as expected to fail
and then rebaseline them later.

  • BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/controllers.js:
  • BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/garden-o-matic.js:
  • BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/model.js:
  • BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/summary-mock.js:
  • BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui.js:
  • BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/notifications.js:
  • BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/notifications_unittests.js:
Location:
trunk/Tools
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/controllers.js

    r94487 r94540  
    6868});
    6969
    70 controllers.UnexpectedFailures = base.extends(Object, {
     70var FailureStreamController = base.extends(Object, {
     71    _resultsFilter: null,
     72    _keyFor: function(failureAnalysis) { throw "Not implemented!"; },
     73    _createFailureView: function(failureAnalysis) { throw "Not implemented!"; },
     74
    7175    init: function(view)
    7276    {
     
    7680    update: function(failureAnalysis)
    7781    {
    78         var key = failureAnalysis.newestPassingRevision + "+" + failureAnalysis.oldestFailingRevision;
     82        var key = this._keyFor(failureAnalysis);
    7983        var failure = this._testFailures.get(key);
    80         var impliedFirstFailingRevision = failureAnalysis.newestPassingRevision + 1;
    8184        if (!failure) {
    82             failure = new ui.notifications.TestsFailing();
    83             model.commitDataListForRevisionRange(impliedFirstFailingRevision, failureAnalysis.oldestFailingRevision).forEach(function(commitData) {
    84                 var suspiciousCommit = failure.addCommitData(commitData);
    85                 $(suspiciousCommit).bind('rollout', function() {
    86                     this.onRollout(commitData.revision, failure.testNameList());
    87                 }.bind(this));
    88                 $(failure).bind('blame', function() {
    89                     this.onBlame(failure, commitData);
    90                 }.bind(this));
    91             }, this);
     85            failure = this._createFailureView(failureAnalysis);
    9286            this._view.add(failure);
    9387            $(failure).bind('examine', function() {
     
    9993        }
    10094        failure.addFailureAnalysis(failureAnalysis);
    101         failure.updateBuilderResults(model.buildersInFlightForRevision(impliedFirstFailingRevision));
    10295        this._testFailures.update(key, failure);
     96        return failure;
    10397    },
    10498    purge: function() {
     
    115109        var testNameList = failures.testNameList();
    116110        var failuresByTest = base.filterDictionary(
    117             results.unexpectedFailuresByTest(model.state.resultsByBuilder),
     111            this._resultsFilter(model.state.resultsByBuilder),
    118112            function(key) {
    119113                return testNameList.indexOf(key) != -1;
     
    136130            alert('Rebaseline done! Please land with "webkit-patch land-cowboy".');
    137131        });
     132    }
     133});
     134
     135controllers.UnexpectedFailures = base.extends(FailureStreamController, {
     136    _resultsFilter: results.expectedOrUnexpectedFailuresByTest,
     137
     138    _impliedFirstFailingRevision: function(failureAnalysis)
     139    {
     140        return failureAnalysis.newestPassingRevision + 1;
     141    },
     142    _keyFor: function(failureAnalysis)
     143    {
     144        return failureAnalysis.newestPassingRevision + "+" + failureAnalysis.oldestFailingRevision;
     145    },
     146    _createFailureView: function(failureAnalysis)
     147    {
     148        var failure = new ui.notifications.FailingTestsSummary();
     149        model.commitDataListForRevisionRange(this._impliedFirstFailingRevision(failureAnalysis), failureAnalysis.oldestFailingRevision).forEach(function(commitData) {
     150            var suspiciousCommit = failure.addCommitData(commitData);
     151            $(suspiciousCommit).bind('rollout', function() {
     152                this.onRollout(commitData.revision, failure.testNameList());
     153            }.bind(this));
     154            $(failure).bind('blame', function() {
     155                this.onBlame(failure, commitData);
     156            }.bind(this));
     157        }, this);
     158
     159        return failure;
     160    },
     161    update: function(failureAnalysis)
     162    {
     163        var failure = FailureStreamController.prototype.update.call(this, failureAnalysis);
     164        failure.updateBuilderResults(model.buildersInFlightForRevision(this._impliedFirstFailingRevision(failureAnalysis)));
    138165    },
    139166    onBlame: function(failure, commitData)
     
    150177        checkout.rollout(revision, ui.rolloutReasonForTestNameList(testNameList), $.noop);
    151178    }
     179});
     180
     181controllers.Failures = base.extends(FailureStreamController, {
     182    _resultsFilter: results.expectedOrUnexpectedFailuresByTest,
     183
     184    _keyFor: function(failureAnalysis)
     185    {
     186        return base.dirName(failureAnalysis.testName);
     187    },
     188    _createFailureView: function(failureAnalysis)
     189    {
     190        return new ui.notifications.FailingTests();
     191    },
    152192});
    153193
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/garden-o-matic.js

    r94204 r94540  
    3131var g_buildersFailing = null;
    3232
    33 var g_unexpectedFailures = null;
     33var g_unexpectedFailuresController = null;
     34var g_failuresController = null;
     35
    3436var g_failingBuilders = null;
    3537
     
    4446
    4547    base.callInParallel([model.updateRecentCommits, model.updateResultsByBuilder], function() {
    46         model.analyzeUnexpectedFailures(g_unexpectedFailures.update.bind(g_unexpectedFailures), function() {
    47             g_unexpectedFailures.purge();
     48        model.analyzeUnexpectedFailures(g_unexpectedFailuresController.update.bind(g_unexpectedFailuresController), function() {
     49            g_unexpectedFailuresController.purge();
    4850            updating.dismiss();
    4951        });
     52
     53        model.analyzeExpectedOrUnexpectedFailures(g_failuresController.update.bind(g_failuresController));
    5054    });
    5155}
     
    6165    onebar.attach();
    6266
    63     var actions = new ui.notifications.Stream();
    64     g_unexpectedFailures = new controllers.UnexpectedFailures(actions);
     67    var unexpectedFailuresView = new ui.notifications.Stream();
     68    g_unexpectedFailuresController = new controllers.UnexpectedFailures(unexpectedFailuresView);
     69
     70    var failuresView = new ui.notifications.Stream();
     71    g_failuresController = new controllers.Failures(failuresView);
    6572
    6673    g_info = new ui.notifications.Stream();
     
    7582    summary.appendChild(updateButton);
    7683    summary.appendChild(g_info);
    77     summary.appendChild(actions);
     84    summary.appendChild(unexpectedFailuresView);
     85
     86    var failures = onebar.failures();
     87    failures.appendChild(failuresView);
    7888
    7989    update();
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/model.js

    r94485 r94540  
    208208};
    209209
     210model.analyzeExpectedOrUnexpectedFailures = function(callback)
     211{
     212    var expectedFailures = results.expectedOrUnexpectedFailuresByTest(model.state.resultsByBuilder);
     213    $.each(expectedFailures, function(testName, resultNodesByBuilder) {
     214        var failureAnalysis = {
     215            'testName': testName,
     216            'resultNodesByBuilder': resultNodesByBuilder,
     217        };
     218
     219        // FIXME: Consider looking at the history to see how long this test
     220        // has been failing.
     221
     222        callback(failureAnalysis);
     223    });
     224};
     225
    210226})();
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/summary-mock.js

    r93906 r94540  
    117117var currentMinutesAgo = 0;
    118118
    119 function createTestsFailing(commitDataCount, failureAnalysisCount, builderFailureCount)
     119function createFailingTestsSummary(commitDataCount, failureAnalysisCount, builderFailureCount)
    120120{
    121     var testsFailing = new ui.notifications.TestsFailing();
     121    var failingTestsSummary = new ui.notifications.FailingTestsSummary();
    122122    for (var i = 0; i < commitDataCount; ++i)
    123         testsFailing.addCommitData({
     123        failingTestsSummary.addCommitData({
    124124            time: minutesAgo(currentMinutesAgo++),
    125125            revision: currentRevision++,
     
    129129        });
    130130    for (var i = 0; i < failureAnalysisCount; ++i)
    131         testsFailing.addFailureAnalysis({
     131        failingTestsSummary.addFailureAnalysis({
    132132            testName: testNames.cycle(),
    133133            resultNodesByBuilder: createResultNodesByBuilder(builderFailureCount)
    134134        });
    135     return testsFailing;
     135    return failingTestsSummary;
    136136}
    137137
     
    155155    button.textContent = 'update';
    156156
    157     actions.add(createTestsFailing(3, 4, 1));
    158     actions.add(createTestsFailing(3, 1, 3));
    159     actions.add(createTestsFailing(1, 20, 1));
     157    actions.add(createFailingTestsSummary(3, 4, 1));
     158    actions.add(createFailingTestsSummary(3, 1, 3));
     159    actions.add(createFailingTestsSummary(1, 20, 1));
    160160    actions.add(createBuildersFailing(1));
    161161    actions.add(createBuildersFailing(8));
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui.js

    r94198 r94540  
    6161                '<li><a href="#results">Results</a></li>' +
    6262                '<li><a href="#commits">Commits</a></li>' +
     63                '<li><a href="#failures">Failures</a></li>' +
    6364            '</ul>' +
    6465            '<div id="summary"></div>' +
    6566            '<div id="results"></div>' +
    66             '<div id="commits">Coming soon...</div>';
     67            '<div id="commits">Coming soon...</div>' +
     68            '<div id="failures"></div>';
    6769        this._tabNames = [
    6870            'summary',
    6971            'results',
    70             'commits,'
     72            'commits',
     73            'failures',
    7174        ]
    7275        this._tabs = $(this).tabs({
     
    8992    {
    9093        return this.tabNamed('results');
     94    },
     95    failures: function()
     96    {
     97        return this.tabNamed('failures');
    9198    },
    9299    select: function(tabName)
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/notifications.js

    r94314 r94540  
    136136    {
    137137        this._time = this._how.appendChild(new ui.RelativeTime());
    138         this._where = this._how.appendChild(new ui.failures.FailureGrid());
    139138        this._problem = this._what.appendChild(document.createElement('div'));
    140139        this._problem.className = 'problem';
     
    150149});
    151150
    152 ui.notifications.TestsFailing = base.extends(ui.notifications.Failure, {
     151ui.notifications.FailingTests = base.extends(ui.notifications.Failure, {
    153152    init: function() {
    154153        // FIXME: Convert actions to a link from test!
     
    158157        ]));
    159158        this._testNameList = [];
    160         this._commitDataPinned = false;
    161159    },
    162160    testNameList: function()
     
    168166        return this._testNameList.indexOf(failureAnalysis.testName) != -1;
    169167    },
    170     updateBuilderResults: function(resultNodesByBuilder)
    171     {
    172         this._where.add(resultNodesByBuilder);
    173     },
    174168    addFailureAnalysis: function(failureAnalysis)
    175169    {
    176170        if (this.containsFailureAnalysis(failureAnalysis))
    177             return;
     171            return false;
    178172        this._testNameList.push(failureAnalysis.testName);
    179         this.updateBuilderResults(failureAnalysis.resultNodesByBuilder);
    180173        $(this._effects).empty();
    181174        this._forEachTestGroup(function (testGroup) {
    182175            this._effects.appendChild(new ui.notifications.FailingTestGroup(testGroup))
    183176        }.bind(this));
    184     },
    185     pinToCommitData: function(commitData)
    186     {
    187         if (this._commitDataPinned)
    188             return;
    189         this._commitDataPinned = true;
    190         $(this._causes).children().each(function() {
    191             if (this.hasRevision(commitData.revision))
    192                 return;
    193             $(this).detach();
    194         });
    195     },
    196     addCommitData: function(commitData)
    197     {
    198         if (this._commitDataPinned)
    199             return null;
    200         var commitDataDate = new Date(commitData.time);
    201         if (this._time.date > commitDataDate); {
    202             this.setIndex(commitDataDate.getTime());
    203             this._time.setDate(commitDataDate);
    204         }
    205         return this._causes.appendChild(new ui.notifications.SuspiciousCommit(commitData));
     177        return true;
    206178    },
    207179    _forEachTestGroup: function(callback)
     
    227199});
    228200
     201ui.notifications.FailingTestsSummary = base.extends(ui.notifications.FailingTests, {
     202    init: function() {
     203        this._where = this._how.appendChild(new ui.failures.FailureGrid());
     204        this._commitDataPinned = false;
     205    },
     206    updateBuilderResults: function(resultNodesByBuilder)
     207    {
     208        this._where.add(resultNodesByBuilder);
     209    },
     210    addFailureAnalysis: function(failureAnalysis)
     211    {
     212        if (!ui.notifications.FailingTests.prototype.addFailureAnalysis.call(this, failureAnalysis))
     213            return false;
     214        this.updateBuilderResults(failureAnalysis.resultNodesByBuilder);
     215    },
     216    pinToCommitData: function(commitData)
     217    {
     218        if (this._commitDataPinned)
     219            return;
     220        this._commitDataPinned = true;
     221        $(this._causes).children().each(function() {
     222            if (this.hasRevision(commitData.revision))
     223                return;
     224            $(this).detach();
     225        });
     226    },
     227    addCommitData: function(commitData)
     228    {
     229        if (this._commitDataPinned)
     230            return null;
     231        var commitDataDate = new Date(commitData.time);
     232        if (this._time.date > commitDataDate); {
     233            this.setIndex(commitDataDate.getTime());
     234            this._time.setDate(commitDataDate);
     235        }
     236        return this._causes.appendChild(new ui.notifications.SuspiciousCommit(commitData));
     237    }
     238});
     239
    229240ui.notifications.BuildersFailing = base.extends(ui.notifications.Failure, {
    230241    init: function()
    231242    {
    232243        this._problem.insertBefore(document.createTextNode('Build Failed:'), this._problem.firstChild);
    233         $(this._where).detach();
    234244    },
    235245    setFailingBuilders: function(builderNameList)
    236246    {
    237         // FIXME: Populate this._where with failing builders.
    238247        $(this._effects).empty().append(builderNameList.map(function(builderName) {
    239248            var effect = document.createElement('li');
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/notifications_unittests.js

    r94314 r94540  
    9999});
    100100
    101 test('TestsFailing', 13, function() {
    102     var testFailures = new ui.notifications.TestsFailing();
    103     deepEqual(Object.getOwnPropertyNames(testFailures.__proto__), [
    104         "init",
    105         "testNameList",
    106         "updateBuilderResults",
    107         "addFailureAnalysis",
    108         "pinToCommitData",
    109         "_forEachTestGroup",
    110         "containsFailureAnalysis",
    111         "addCommitData"
    112     ]);
     101test('FailingTestsSummary', 12, function() {
     102    var testFailures = new ui.notifications.FailingTestsSummary();
    113103    equal(testFailures.tagName, 'LI');
    114104    equal(testFailures.innerHTML,
     
    305295});
    306296
    307 test('TestsFailing (grouping)', 1, function() {
    308     var testFailures = new ui.notifications.TestsFailing();
     297test('FailingTestsSummary (grouping)', 1, function() {
     298    var testFailures = new ui.notifications.FailingTestsSummary();
    309299    testFailures.addFailureAnalysis({testName: 'path/to/test1.html', resultNodesByBuilder: {}});
    310300    testFailures.addFailureAnalysis({testName: 'path/to/test2.html', resultNodesByBuilder: {}});
  • trunk/Tools/ChangeLog

    r94539 r94540  
     12011-09-05  Adam Barth  <abarth@webkit.org>
     2
     3        Add a tab to garden-o-matic for viewing expected failures
     4        https://bugs.webkit.org/show_bug.cgi?id=67619
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        This patch adds a basic tab to garden-o-matic that shows all the tests
     9        failing on the bots, including the expected failures.  This patch
     10        mostly involves refactoring existing classes to allow new subclasses.
     11
     12        This view is useful for when gardeners mark tests as expected to fail
     13        and then rebaseline them later.
     14
     15        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/controllers.js:
     16        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/garden-o-matic.js:
     17        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/model.js:
     18        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/summary-mock.js:
     19        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui.js:
     20        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/notifications.js:
     21        * BuildSlaveSupport/build.webkit.org-config/public_html/TestFailures/scripts/ui/notifications_unittests.js:
     22
    1232011-09-05  Adam Barth  <abarth@webkit.org>
    224
Note: See TracChangeset for help on using the changeset viewer.