OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Use the JSON functionality to parse a json string, and fallback to | |
6 // the eval method is JSON is not supported by the browser. | |
7 function parseJSON(data) { | |
8 if (typeof (JSON) !== 'undefined' && | |
9 typeof (JSON.parse) === 'function') { | |
10 return JSON.parse(data); | |
11 } else { | |
12 return eval('(' + data + ')'); | |
13 } | |
14 } | |
15 | |
16 // Return the name associated with a buildbot result code. | |
17 function getResultName(result) { | |
18 if (result == 0) { | |
19 return 'success'; | |
20 } else if (result == 2) { | |
21 return 'failure'; | |
22 } else { | |
23 return 'exception'; | |
24 } | |
25 } | |
26 | |
27 // Parse the JSON of the reliability builder page and return the list of recent | |
28 // builds, newest first. | |
29 function parseReliability(xmlHttp) { | |
30 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { | |
31 var reliabilityData = parseJSON(xmlHttp.responseText); | |
32 cachedBuilds = reliabilityData['cachedBuilds']; | |
33 cachedBuilds.sort(); | |
34 cachedBuilds.reverse(); | |
35 return cachedBuilds; | |
36 } | |
37 | |
38 return null; | |
39 } | |
40 | |
41 // Parse the JSON of a reliability build and return it. | |
42 function parseBuild(xmlHttp) { | |
43 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { | |
44 return parseJSON(xmlHttp.responseText); | |
45 } | |
46 return null; | |
47 } | |
48 | |
49 // Parse the stdio from a reliability build and return the crash results. | |
50 // NOTE: This function is highly dependent on the format of the text generated | |
51 // by the reliability script. It will break if the format changes. | |
52 function parseStdio(xmlHttp) { | |
53 var buildResults = {}; | |
54 buildResults.webCrash = null; | |
55 buildResults.webCount = null; | |
56 buildResults.uiCrash = null; | |
57 buildResults.uiCount = null; | |
58 | |
59 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { | |
60 lines = xmlHttp.responseText.split('\n'); | |
61 for (var i = 0; i < lines.length; i++) { | |
62 var re = new RegExp('\\bsuccess: (\\d+); crashes: (\\d+); ' + | |
63 'crash dumps: (\\d+); timeout: (\\d+)\\b'); | |
64 var match = re.exec(lines[i]); | |
65 if (match != null) { | |
66 if (buildResults.webCrash == null) { | |
67 buildResults.webCrash = match[2]; | |
68 buildResults.webCount = match[1]; | |
69 } else { | |
70 buildResults.uiCrash = match[2]; | |
71 buildResults.uiCount = match[1]; | |
72 } | |
73 } | |
74 } | |
75 } | |
76 return buildResults; | |
77 } | |
78 | |
79 function displayReliability() { | |
80 var xmlHttp = new XMLHttpRequest(); | |
81 var jsonPath = '../chromium/json/builders/Win%20Reliability'; | |
82 var buildPath = '../chromium/builders/Win%20Reliability/builds/'; | |
83 // NOTE: This will break if the name of the step changes. | |
84 var stepLog = '/steps/reliability%3A%20partial%20result%20of%20current%20' + | |
85 'build/logs/stdio'; | |
86 | |
87 // Get the main reliability page. | |
88 xmlHttp.open('GET', jsonPath, false); | |
89 xmlHttp.send(null); | |
90 var cachedBuilds = parseReliability(xmlHttp); | |
91 | |
92 // Information we need to get from the builds. | |
93 var lastBuild = null; | |
94 var lastSuccess = null; | |
95 var lastResult = null; | |
96 | |
97 // Iterate through all the builds to find the last one that is finished and | |
98 // the last green build. | |
99 if (cachedBuilds != null) { | |
100 for (var i = 0; i < cachedBuilds.length; i++) { | |
101 xmlHttp.open('GET', jsonPath + '/builds/' + cachedBuilds[i], false); | |
102 xmlHttp.send(null); | |
103 var currentBuild = parseBuild(xmlHttp); | |
104 | |
105 if (currentBuild != null) { | |
106 if (lastBuild == null && currentBuild['results'] != null) { | |
107 lastBuild = currentBuild; | |
108 lastResult = getResultName(currentBuild['results']); | |
109 } | |
110 | |
111 if (currentBuild['results'] == 0) { | |
112 lastSuccess = currentBuild; | |
113 } | |
114 } | |
115 | |
116 if (lastBuild != null && lastSuccess != null) { | |
117 break; | |
118 } | |
119 } | |
120 } | |
121 | |
122 // Information we need to get from the last finished build. | |
123 var buildResults = null; | |
124 var lastLog = null; | |
125 | |
126 // Fetch the crash count. | |
127 if (lastBuild != null) { | |
128 lastLog = buildPath + lastBuild['number'] + stepLog; | |
129 xmlHttp.open('GET', lastLog, false); | |
130 xmlHttp.send(null); | |
131 buildResults = parseStdio(xmlHttp); | |
132 } | |
133 | |
134 var topBox = document.getElementById('ReliabilityTop'); | |
135 var bottomBox = document.getElementById('ReliabilityBottom'); | |
136 | |
137 // Update the top box. | |
138 if (lastBuild == null || buildResults.webCrash == null || | |
139 buildResults.uiCrash == null) { | |
140 // No information about the current build. | |
141 topBox.className = 'exception'; | |
142 topBox.innerHTML = '<p style="margin-bottom: 25px; margin-top: 20px">' + | |
143 'stats<br>not available</p>'; | |
144 } else { | |
145 // TODO(nsylvain): Get full range. | |
146 var rev = lastBuild['sourceStamp']['revision']; | |
147 var revisionRange = rev + ' : ' + rev; | |
148 var webUrl = 'http://chromebot/buildsummary?id=buildbot_' + rev + '_ext'; | |
149 var webCrashStr = buildResults.webCrash + ' / ' + | |
150 buildResults.webCount + ' URLs'; | |
151 var uiUrl = 'http://chromebot/buildsummary?id=ui_buildbot_' + rev; | |
152 var uiCrashStr = buildResults.uiCrash + ' / ' + | |
153 buildResults.uiCount + ' UI Ops'; | |
154 | |
155 var text = '<p style="margin-bottom: 7px; margin-top: 2px;">' + | |
156 '<a href="' + lastLog + '">' + revisionRange + '</a>' + | |
157 '<br><br>Crashes:<br>' + | |
158 '<a href="' + webUrl + '">' + webCrashStr + '</a><br>' + | |
159 '<a href="' + uiUrl + '">' + uiCrashStr + '</a></p>'; | |
160 | |
161 topBox.className = lastResult; | |
162 topBox.innerHTML = text; | |
163 } | |
164 | |
165 // Update the bottom box. | |
166 if (lastResult == 'success') { | |
167 var d = new Date(); | |
168 var diff_ms = d.getTime() - (lastBuild['times'][1] * 1000); | |
169 var diff_minute = parseInt(diff_ms / 1000 / 60); | |
170 | |
171 bottomBox.className = 'success'; | |
172 bottomBox.innerHTML = diff_minute + ' minutes ago'; | |
173 } else if (lastSuccess != null) { | |
174 var rev = lastSuccess['sourceStamp']['revision']; | |
175 var lastGreenLog = buildPath + lastSuccess['number'] + stepLog; | |
176 var text = 'Last green: <a href="' + lastGreenLog + '">' + rev + '</a>'; | |
177 | |
178 bottomBox.className = 'success' | |
179 bottomBox.innerHTML = text; | |
180 } else { | |
181 bottomBox.className = topBox.className; | |
182 bottomBox.innerHTML = ' '; | |
183 } | |
184 } | |
OLD | NEW |