Rename TestFailureBugForm to FailingTestsBugForm
[WebKit-https.git] / Tools / BuildSlaveSupport / build.webkit.org-config / public_html / TestFailures / FailingTestsBugForm.js
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 // FIXME: These should probably move to some WebKitBugzilla class (or similar).
27 const BugzillaConstants = {
28     Component: {
29         ToolsTests: 'Tools / Tests',
30     },
31
32     Keyword: {
33         LayoutTestFailure: 'LayoutTestFailure',
34         MakingBotsRed: 'MakingBotsRed',
35         Regression: 'Regression',
36     },
37
38     OperatingSystem: {
39         Leopard: 'Mac OS X 10.5',
40         SnowLeopard: 'Mac OS X 10.6',
41         Windows7: 'Windows 7',
42         WindowsXP: 'Windows XP',
43     },
44
45     Platform: {
46         Macintosh: 'Macintosh',
47         PC: 'PC',
48     },
49
50     Product: {
51         WebKit: 'WebKit',
52     },
53
54     Version: {
55         Nightly: '528+ (Nightly Build)',
56     },
57 };
58
59 function FailingTestsBugForm(bugzilla, trac, tester, failingBuildName, passingBuildName, failingTests) {
60     NewBugForm.call(this, bugzilla);
61
62     this._trac = trac;
63     this._tester = tester;
64     this._failingBuildName = failingBuildName;
65     this._passingBuildName = passingBuildName;
66     this._failingTests = failingTests;
67
68     this.component = BugzillaConstants.Component.ToolsTests;
69     this.description = this._createBugDescription();
70     // FIXME: When a newly-added test has been failing since its introduction, it isn't really a
71     // "regression". We should use different keywords in that case. <http://webkit.org/b/61645>
72     this.keywords = [
73         BugzillaConstants.Keyword.LayoutTestFailure,
74         BugzillaConstants.Keyword.MakingBotsRed,
75         BugzillaConstants.Keyword.Regression
76     ].join(', ');
77     this.operatingSystem = this._computeOperatingSystem();
78     this.platform = this._computePlatform();
79     this.product = BugzillaConstants.Product.WebKit;
80     this.title = this._createBugTitle();
81     this.url = this._failingResultsHTMLURL();
82     this.version = BugzillaConstants.Version.Nightly;
83 }
84
85 FailingTestsBugForm.prototype = {
86     domElement: function() {
87         var form = NewBugForm.prototype.domElement.call(this);
88         form.className = 'new-bug-form';
89         form.target = '_blank';
90         return form;
91     },
92
93     _computeOperatingSystem: function() {
94         if (/Windows 7/.test(this._tester.name))
95             return BugzillaConstants.OperatingSystem.Windows7;
96         if (/Windows XP/.test(this._tester.name))
97             return BugzillaConstants.OperatingSystem.WindowsXP;
98         if (/SnowLeopard/.test(this._tester.name))
99             return BugzillaConstants.OperatingSystem.SnowLeopard;
100         if (/Leopard/.test(this._tester.name))
101             return BugzillaConstants.OperatingSystem.Leopard;
102         return '';
103     },
104
105     _computePlatform: function() {
106         if (/Windows/.test(this._tester.name))
107             return BugzillaConstants.Platform.PC;
108         if (/Leopard/.test(this._tester.name))
109             return BugzillaConstants.Platform.Macintosh;
110         return '';
111     },
112
113     _createBugDescription: function() {
114         var firstSuspectRevision = this._passingRevision() ? this._passingRevision() + 1 : this._failingRevision();
115         var lastSuspectRevision = this._failingRevision();
116
117         var endOfFirstSentence;
118         if (this._passingBuildName) {
119             endOfFirstSentence = 'started failing on ' + this._tester.name;
120             if (firstSuspectRevision === lastSuspectRevision)
121                 endOfFirstSentence += ' in r' + firstSuspectRevision + ' <' + this._trac.changesetURL(firstSuspectRevision) + '>';
122             else
123                 endOfFirstSentence += ' between r' + firstSuspectRevision + ' and r' + lastSuspectRevision + ' (inclusive)';
124         } else
125             endOfFirstSentence = (this._failingTests.length === 1 ? 'has' : 'have') + ' been failing on ' + this._tester.name + ' since at least r' + firstSuspectRevision + ' <' + this._trac.changesetURL(firstSuspectRevision) + '>';
126         var description;
127         if (this._failingTests.length === 1)
128             description = this._failingTests[0] + ' ' + endOfFirstSentence + '.\n\n';
129         else if (this._failingTests.length === 2)
130             description = this._failingTests.join(' and ') + ' ' + endOfFirstSentence + '.\n\n';
131         else {
132             description = 'The following tests ' + endOfFirstSentence + ':\n\n'
133                 + this._failingTests.map(function(test) { return '    ' + test }).join('\n')
134                 + '\n\n';
135         }
136         if (firstSuspectRevision !== lastSuspectRevision)
137             description += this._trac.logURL('trunk', firstSuspectRevision, lastSuspectRevision) + '\n\n';
138         if (this._passingBuildName)
139             description += this._tester.resultsPageURL(this._passingBuildName) + ' passed\n';
140         description += this._failingResultsHTMLURL() + ' failed\n';
141
142         return description;
143     },
144
145     _createBugTitle: function() {
146         // FIXME: When a newly-added test has been failing since its introduction, it isn't really a
147         // "regression". We should use a different title in that case. <http://webkit.org/b/61645>
148
149         var titlePrefix = 'REGRESSION (' + this._regressionRangeString() + '): ';
150         var titleSuffix = ' failing on ' + this._tester.name;
151         var title = titlePrefix + this._failingTests.join(', ') + titleSuffix;
152
153         if (title.length <= Bugzilla.maximumBugTitleLength)
154             return title;
155
156         var pathPrefix = longestCommonPathPrefix(this._failingTests);
157         if (pathPrefix) {
158             title = titlePrefix + this._failingTests.length + ' ' + pathPrefix + ' tests' + titleSuffix;
159             if (title.length <= Bugzilla.maximumBugTitleLength)
160                 return title;
161         }
162
163         title = titlePrefix + this._failingTests.length + ' tests' + titleSuffix;
164
165         console.assert(title.length <= Bugzilla.maximumBugTitleLength);
166         return title;
167     },
168
169     _failingResultsHTMLURL: function() {
170         return this._tester.resultsPageURL(this._failingBuildName);
171     },
172
173     _failingRevision: function() {
174         return this._tester.buildbot.parseBuildName(this._failingBuildName).revision;
175     },
176
177     _passingRevision: function() {
178         if (!this._passingBuildName)
179             return null;
180         return this._tester.buildbot.parseBuildName(this._passingBuildName).revision;
181     },
182
183     _regressionRangeString: function() {
184         var failingRevision = this._failingRevision();
185         var passingRevision = this._passingRevision();
186         if (!passingRevision || failingRevision - passingRevision <= 1)
187             return 'r' + failingRevision;
188         return 'r' + passingRevision + '-r' + failingRevision;
189     },
190 };
191
192 FailingTestsBugForm.prototype.__proto__ = NewBugForm.prototype;